14_1_Spring的IOC和DI

一.spring的概述

1.Spring框架是什么

Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多 著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。

2. Spring起源

1997 年 IBM 提出了 EJB 的思想 1998 年, SUN 制定开发标准规范 EJB1.0 1999 年, EJB1.1 发布 2001 年, EJB2.0 发布 2003 年, EJB2.1 发布 2006 年, EJB3.0 发布 Rod Johnson(spring 之父) Expert One-to-One J2EE Design and Development(2002) 阐述了 J2EE 使用 EJB 开发设计的优点及解决方案 Expert One-to-One J2EE Development without EJB(2004) 阐述了 J2EE 开发不使用 EJB 的解决方式(Spring 雏形)

 

3. spring框架的优势

方便解耦,简化开发 通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

AOP 编程的支持 通过 Spring 的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付。

声明式事务的支持 可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。

方便程序的测试 可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

方便集成各种优秀框架 Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、 Quartz等)的直接支持。

降低 JavaEE API 的使用难度

Spring 对 JavaEE API(如 JDBC、JDBCTemplate . JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。

Java源码是经典学习范例

Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以及对 Java 技术的高深造诣。它的源代码无意是 Java 技术*的最佳实践的范例.

4. Spring架构体系

 

Test :用于测试使用

Core container:核心容器,就是用于装Java Bean对象

AOP:切面编程

Aspects:提供了与AspectJ的集成

Data access:数据访问。用于访问操作我们的数据库。支持持久层的操作。jdbcTemplate mybatis

Web:用于支持数据展示层,支持http请求

Transactions:用于支持事物处理。用于解决业务层的事物处理问题。 编程式事务管理和声明式事务管理.

 

二.控制反转

1.概念:什么是IOC

控制反转,把原理new对象的这种方式转换成了,spring通过反射创建对象的方式, spring创建完的对象放到一个容器中,谁需要就给谁注入进去. 简单说:把创建对象和管理对象的权利交给spring

2.如何来实现IOC进行创建对象和管理对象

 

3.控制反转的入门案例

1.准备环境

  • 导入spring所需要的4个jar

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

2.需求: 创建一个UserService , 里面有一个属性username ,有一个play的方法;

接下来使用spring来创建该对象并给该对象的username属性值设置值. 最后使用junit进行测试.

实现步骤:

1.编写一个类UserService

package com.itheima.ioc;
/**
 * 需求: 创建一个UserService , 里面有一个属性username ,有一个play的方法;
 * 接下来使用spring来创建改对象并给该对象的username属性值设置值. 最后使用junit进行测试.
 *
 * 实现步骤:
 * 1.pom.xml中到如jar
 * 2.创建applicationContext.xml
 * 3.创建UserService 类,提供属性username  setter  getter  play方法
 * 4.在applicationContext.xml做配置
 * 5.编写测试类
 *    5.1 获取spring的容器对象(加载applicationContext.xml)
 *    5.2 调用getBean(id)得到UserService对象
 *    5.3 调用对象的play方法 (是否调用成功username是否被初始化)
 */
public class UserService {
    private String username;

    public void play(){
        System.out.println(username);
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

}

2.编写applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--
        bean标签 用于创建对象, 根据我们配置的完全路径通过反射创建对象.
        作用效果: UserService service = new UserSerivce();
    -->
    <bean id="userService" class="com.itheima.service.UserService">
        <!--
            property ,通过反射条用set方法,给对象的username设置属性
        -->
        <property name="username" value="柯正恶"></property>
    </bean>
</beans>

3.编写测试类

package com.itheima.service;


import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * * 5.编写测试类
 *    5.1 获取spring的容器对象(加载applicationContext.xml)
 *    5.2 调用getBean(id)得到UserService对象
 *    5.3 调用对象的play方法 (是否调用成功username是否被初始化)
 */
public class UserServiceTest {

    @Test
    public void play() {
        //5.1 获取spring的容器对象(加载applicationContext.xml)
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //5.2 调用getBean(id)得到UserService对象
        UserService userService = (UserService) context.getBean("userService");
        // 5.3 调用对象的play方法 (是否调用成功username是否被初始化)
        userService.play();
    }
}

4.通过构造方法创建对象

1)编写一个User类, 目的是使用无参构造创建他的对象

package com.itheima.ioc;

public class User {
    public User() {
        System.out.println("柳岩的无参构造方法");
    }
}

2)编写applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--创建User对象,
        bean:spring框架内部回解析bean标签,创建对象java中所有类,都认为是一个bean对象
        id:创建好的对象的唯一标识,通过getBean()获取spring已经创建好的对象
        class:类的完全路径名,在框架内部做反射使用.
    -->
    <bean id="user" class="com.itheima.ioc.User"></bean>
</beans>

3)编写测试类

package com.itheima.ioc;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/*
 * 目的:查看是否调用了无参构造方法  ?
 * 问题1:  哪一行代码执行会调用无参构造方法
 * ApplicationContext context    会创建对象
 * UserService userService     获取spring容器中创建好的对象
 *
 * 问题2:如果不加强转,能够直接返回我们想要的对象
 * context.getBean("userService", User.class);
 *
 * 问题3:
 * 两种加载配置文件的方式
 * 该对象制度classpath下的配置文件
 * ApplicationContext context = newClassPathXmlApplicationContext("ApplicationContext");
 *
 *
 * 加载绝对路径下的配置文件
 * ApplicationContext context1 = new FileSystemXmlApplicationContext("E:\\WorkSpace\\IdeaWS\\JavaWeb\\day18_spring\\target\\classes\\ApplicationContext");
 *
 * */
public class UserTest {
    @Test
    public void testUser01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext");

//        ApplicationContext context1 = new FileSystemXmlApplicationContext("E:\\WorkSpace\\IdeaWS\\JavaWeb\\day18_spring\\target\\classes\\ApplicationContext");

        User user = (User) context.getBean("user");

//        User user1 = context.getBean("user", User.class);

        System.out.println(user);
    }

5.静态工厂创建对象

1.首先会提供了一个工厂类,工厂中有提供了创建对象的方法.

/**
 * 需求: 使用静态工厂的方式创建对象, 由spring配置方式创建
 *
 * 实现步骤:
 * 1.创建工厂类
 * 2.工厂类中编写一个静态方法, (返回执行类User)
 * 3.applicationContext.xml中配置如何创建
 * 4.测试,通过静态工厂获取对象
 */
public class UserStaticFactory {
    //静态方法创建user并返回
    public static User getUser(){
        return new User();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        通过静态工厂获取user对象
        id: 获取user类的id
        class 工厂的全类名
        factory-method :工厂的指定获取user的方法
    -->
    <bean id="user01" class="com.itheima.ioc.UserStaticFactory" factory-method="getUser"></bean>

</beans>
 //1.静态工厂的测试,获取user对象
    @Test
    //4.测试,通过静态工厂获取对象
    public void test01(){

        //1.获取Context容器 ,
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.getBean获取user对象
        User user = context.getBean("user02", User.class);
        //3.打印
        System.out.println(user);
    }

6.实例工厂创建对象

1)编写一个实例工厂,目的创建User对象

/**
 * 实例工厂获取user对象
 */
public class UserFactory {
    public User getUser() {
        return new User();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--
        通过实例工厂创建user对象
        3.1 先创建实例工厂对象
        3.2 再创建user对象
    -->
    <bean id="factory" class="com.itheima.ioc.UserFactory"></bean>
    <bean id="user02" factory-bean="factory" factory-method="getUser"></bean>
</beans>
    /*测试使用实例工厂获取user对象*/
    @Test
    public void testUser03(){
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext");
        User user02 = context.getBean("user02", User.class);

        System.out.println(user02);
    }

7.spring创建对象的范围

问题: 每次获取对象的时候,spring是新创建一个对象还是始终给我们返回同一个对象.

单例: 内存中只有一个对象,每次获取到该对象的地址值一样.

多例:内存中的每个对象都是一个新的对象,他们的地址值都不同.

1.答案: spring默认的情况下创建的对象都是单例的. (每次返回的对象都是同一个)

测试:

 <!--1.通过构造方法创建User对象
        scope="singleton" 单例(默认值)
        scope="prototype" 多例

        scope="request" 创建的对象放到request域中
        scope="session" 创建对象放到session对象
    -->
    <bean id="user" class="com.itheima.ioc.User" scope="singleton"></bean>


    <bean id="user" class="com.itheima.ioc.User" scope="prototype"></bean>
/**
     * 判断spring创建的user对象是单例还是多例
     * 1.默认情况下spring创建的对象是单例的
     *
     * 2.想让spring创建的对象每次都不一样,创建多例对象
     * 如果我们将scope="prototype" , 调用getBean的时候创建对象
     */
    @Test
    public void testUser04(){
        //1.获取spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.调用getBean方法得到user
        User user1 = (User) context.getBean("user");

        User user2 = (User) context.getBean("user");

        User user3 = (User) context.getBean("user");

        System.out.println(user1);
        System.out.println(user2);
        System.out.println(user3);
    }

8.spring创建对象的生命周期 

1)spring创建的对象什么时候创建,什么时候运行,什么时候销毁.

结论:1. 配置文件加载的时候对象就创建, 2.当使用该对象的时候就运行 3.当spring的容器关闭的时候对象销毁

测试:

package com.itheima.life;

public class Student  {

    public void init(){
        System.out.println("stu对象创建了");
    }

    public void service(){
        System.out.println("stu对象的service方法执行了");
    }

    public void destroy(){
        System.out.println("stu 对象销毁了.");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--spring创建对象的生命周期
        init-method 当该对象初始化的时候该方法会自动执行
        destroy-method 当该对象即将销毁的时候会自动调用该方法
     -->
    <bean id="stu" class="com.itheima.life.Student" init-method="init" destroy-method="destroy"></bean>
</beans>
package com.itheima.life;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import static org.junit.Assert.*;

public class StudentTest {

    //测试student的生命周期

    /**
     * 1.debug执行查看结果
     * 2.执行到哪一个行init方法会执行  21
     * 3.执行到哪一行service方法执行   23
     * 4.执行到哪一个行destroy执行    容器关闭 close()   ClassPathXmlApplicationContext
     */
    @Test
    public void testLife(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        Student stu = context.getBean("stu", Student.class);
        stu.service();
        context.close();  //容器关闭
    }
}

三.依赖注入

1.概念

DI (dependency injection) 依赖注入

含义:就是给对象的属性设置值.

原来给对象的属性设置值: set方法给对象设置值 构造方法给对象初始化的时候设置值.

2.set方式设置属性

前提条件类中必须有set方法

首先创建Person类

package com.itheima.ioc;

import java.util.Date;

/**
 * 需求:使用set方式给person的属性注入值
 * <p>
 * 1.创建属性,并提供set方法
 * 2.spring配置文件中,先创建对象<bean id class> <property name="" value="">  </bean>
 * 3.测试,获取对象,打印对象的属性
 */
public class Person {
    private String name;
    private Date birthday;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--使用spring创建一个日期-->

    <bean id="datee" class="java.util.Date"></bean>
    <bean id="person" class="com.itheima.ioc.Person">
        <!--
            name : 代表的是set方法去掉set,首字母小写
            value: 基本类型或字符串类型的值,具体给属性设置用的
            ref (引用) : 引用对象的id,作为一个对象类型注入
        -->
        <property name="name" value="wenboao"></property>
        <property name="birthday" ref="datee"></property>
    </bean>
</beans>
    /**
     * 测试目标: 获取person对象,查看person的属性是否有值. 通过set注入
     *
     * 注意事项: spring配置文件中 , name属性是set方法去掉set首字母小写  <property name="name" value="柳岩"></property>
     */    
    @Test
    public void a(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Person person = context.getBean("person", Person.class);
        System.out.println(person);
    }

3.构造方式注入

前提条件类中必须有有参构造方法

1.编写Person类

package com.itheima.ioc;

import java.util.Date;

/**
 * 必须提供有参构造方法
 */
public class Person1 {

    private String name;

    private Date birthday;

    public Person1() {
    }

    public Person1(String name, Date birthday) {

        this.name = name;

        this.birthday = birthday;
    }


    @Override
    public String toString() {
        return "Person1{" +

                ", name='" + name + '\'' +

                ", birthday=" + birthday +
                '}';
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--使用spring创建一个日期-->
    <bean id="datee" class="java.util.Date"></bean>
    <!--采用构造方法创建对象-->
    <bean id="person1" class="com.itheima.ioc.Person1">
        <!--
            constructor-arg 构造方法注入
            name 代表的构造方法上的属性名称
            value 代表传递的属性值(基本+String)
            ref  注入的是引用类型
        -->
        <constructor-arg name="name" value="wenboao"/>
        <constructor-arg name="birthday" ref="datee"/>
    </bean>

</beans>
  @Test
    public void testPerson02(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("personbean.xml");
        Person person = context.getBean("person02", Person1.class);
        System.out.println(person);
    }

4.p名称空间注入和c名称空间注入

P代表propertory 属性, 是set注入的简化方式 (提供set方法)

C代表Constructor 构造注入的简化方式 (提供构造方法)

实现步骤

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 <bean id="birthday" class="java.util.Date"></bean>
    <!--使用p名称空间注入属性-->
    <bean id="person_p" class="com.itheima.di.Person" p:id="3" p:userName="杨过" p:age="22" p:birthday-ref="birthday"/>

    <!--使用c名称空间注入-->
    <bean id="person_c" class="com.itheima.di.Person" c:id="3" c:name="雕" c:age="220" c:birthday-ref="birthday"/>

</beans>

5.复杂数据类型注入

我们的类中属性Aarry 数组 List 集合 Map集合 Set集合 Properties集合,如何给这些属性设置值.

package com.itheima.listmap;

import com.itheima.ioc.Person;

import java.util.*;

/**
 * 采用的是set方式注入
 */
public class ComplexBean {
    private String[] arr;
    private List<Person> list;
    private Set<String> set;
    private Map<String, Person> map;
    private Properties properties;

    public String[] getArr() {
        return arr;
    }

    public void setArr(String[] arr) {
        this.arr = arr;
    }

    public List<Person> getList() {
        return list;
    }

    public void setList(List<Person> list) {
        this.list = list;
    }

    public Set<String> getSet() {
        return set;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public Map<String, Person> getMap() {
        return map;
    }

    public void setMap(Map<String, Person> map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "ComplexBean{" +
                "arr=" + Arrays.toString(arr) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}

配置文件

<!--注入复杂数据类型-->
    <bean id="complexBean" class="com.itheima.di.ComplexBean">
        <!--1.先注入数组-->
        <property name="arr">
            <array>
                <value>柯镇恶</value>
                <value>郭靖</value>
                <value>杨过</value>
            </array>
        </property>
        <!--2.注入list类型-->
        <property name="list">
            <list>
               <ref bean="person" />
                <ref bean="person02" />
                <ref bean="person_p" />
            </list>
        </property>

        <!--3.注入set集合-->
        <property name="set">
            <set>
                <value>乔峰</value>
                <value>段誉</value>
                <value>虚竹</value>
            </set>
        </property>

        <!--4.注入map-->
        <property name="map">
            <map>
                <entry key="志平" value-ref="person"/>
                <entry key="小龙女" value-ref="person02"/>
                <entry key="杨过" value-ref="person_p"/>
            </map>
        </property>

        <!--5.注入properties-->
        <property name="properties">
            <props>
                <prop key="no1">石破天</prop>
                <prop key="no2">虚竹</prop>
                <prop key="no3">张无忌</prop>
            </props>
        </property>
    </bean>
public class ComplexBeanTest {

    @Test
    public void testComplexBean(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("personbean.xml");
        ComplexBean complexBean = context.getBean("complexBean", ComplexBean.class);
        String[] arr = complexBean.getArr();
        System.out.println(Arrays.toString(arr));
        System.out.println("---------------------");
        List<Person> list = complexBean.getList();
        for (Person person : list) {
            System.out.println(person);
        }

        System.out.println("---------------------");
        Set<String> set = complexBean.getSet();
        System.out.println(set);
        System.out.println("---------------------");

        Map<String, Person> map = complexBean.getMap();
        Set<Map.Entry<String, Person>> entrySet = map.entrySet();
        for (Map.Entry<String, Person> entry : entrySet) {
            System.out.println(entry.getKey()+ " "+ entry.getValue());
        }
        
        System.out.println("---------------------");
        Properties properties = complexBean.getProperties();
        System.out.println(properties);
    }
}

四.注解方式的IOC和DI

1.使用注解方式创建对象

要求:

1.需要导入一个aop.jar的jar ,该包已经被spring-context.jar依赖引入了.不需要再导入

2.在配置文件中需要进行一个包扫描的配置

需求:创建一个UserService接口,创建他的实现类UserServiceImpl 编写一个方法 findUser方法

在测试类中采用注解的方式获取到该实现类对象并调用他的方法.

目的:掌握注解方式创建对象

annotationBean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <!--
        使用注解方式进行创建对象
        1.开启注解扫描

        含义:开启注解扫描,指定了 base-package 扫描指定的包,扫描包中所有的类
        查看类上是否有指定的注解, 如果类上有指定的注解,那么就创建该类对象,
        放到spring容器中
    -->
    <context:component-scan base-package="com.itheima.annotation"/>
</beans>
public interface UserService {
    public void addUser();
}



/**
 * 需求:
 * 1. 使用注解方式创建UserService的实现类对象,并调用其方法测试
 *
 * 实现的步骤:
 * 1.要在spring配置文件 bean2.xml 中进行注解扫描
 * 2.要给实现类上添加指定的注解,让spring扫描
 * 3.编写测试,获取对象,调用方法
 */

/**
 * IOC注入的注意事项:
 * 1.bean id 我们可以自己设置  @Component("abc")  ===> <bean id="abc" class="com.itheima.annotation.UserServiceImpl">
 *
 * 2.相关的注解还有4个 , 他们的作用都是用来创建对象,功能一样.
 *  @Component    如果不确定是那一层,统统使用该注解
 *  @Repository  建议在数据访问层  dao层的实现类上使用
 *  @Service     建议在service层使用
 *  @Controller  建议在表现层使用   在springMVC中只能使用它
 */
//Component注解就会被spring扫描到,相当于<bean id="userServiceImpl" class="com.itheima.annotation.UserServiceImpl"/>
@Component("abc")
public class UserServiceImpl implements UserService{
    public void addUser() {
        System.out.println("UserServiceImpl--->addUser  执行了");
    }
}
    @Test
    public void c(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        UserService abc = context.getBean("abc", UserService.class);
        abc.addUser();
    }

2.使用注解方式注入

在Service中使用注解的方式注入Dao对象

第一种注入方式

UserDao接口及其实现类

public interface UserDao {
    public void daoAddUser();
}


import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements UserDao {
    public void daoAddUser() {
        System.out.println("UserDaoImpl  的  daoAddUser方法执行了");
    }
}

UserService接口及其实现类

public interface UserService {
    public void addUser();
}


package com.itheima.annotation;

@Service("abc")
public class UserServiceImpl implements UserService {
    /*
    * @Autowired  会自动根据UserDao的类型,在spring容器中查找UserDao的实现类
    * 将实现类赋值给成员变量dao
    * */
    //!!!问题:如果该父类有两个子类 UserDao的子类   UserDaoImpl   UserDaoImpl02
    //无法确定使用哪一个,我们需要添加一个注解来确定注入哪一个

    /**
     * 第一种注入方式:
     * 注入UserDao的实现类
     * @Autowired 自动注入,写在类的成员变量上, 可以根据UserDao接口,创建该接口的实现类,在自动的设置到该成员变量上
     */
    @Autowired
    @Qualifier("userDaoImpl")  //设置子类的bean  id  来确定注入的是哪个子类对象 
    private UserDao dao;

    public void addUser() {
        System.out.println("UserServiceImpl--->addUser  执行了");
        dao.daoAddUser();
    }
}

    @Test
    public void c(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        UserService abc = context.getBean("abc", UserService.class);
        abc.addUser();
    }



/*
测试结果:
UserServiceImpl--->addUser  执行了
UserDaoImpl  的  daoAddUser方法执行了

*/

第二种注入方式


    /**
     * 第二种注入方式:
     * @Value("#{bean的id}")
     */

    @Value("#{userDaoImpl02}")
    private UserDao dao;

    @Value("柳岩")
    private String name;

第三种注入方式

    /**
     * 第三种注入方式 : 是jdk的注解不是spring
     *  @Resource(name="bean的id值")
     */
    @Resource(name="userDaoImpl")
    private UserDao dao;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值