spring中的依赖注入DI

Spring 通过IOC实现对象的管理,而IOC的具体实现,依赖于DI依赖注入对对象的属性进行赋值。

DI 通过配置文件或注解的方式指定对象与对象之间的依赖关系,并依据该依赖关系对对象属性进行赋值。

DI依赖注入的方式:

1) set方法注入:类中的属性必须实现set方法。在bean标签中配置<property> 标签,指定set注入的依赖关系(在xml配置中使用最多);

private BbyeService byeService;

public void setByeService(BbyeService byeService){
          this.byeService=byeService;
}
    <bean id="eByeService" class="spring.EByeService"></bean>
    <bean id="zByeService" class="spring.ZByeService"></bean>
    <bean id="userAction" class="spring.UserAction">
<!--       set注入,类中的属性必须实现set方法,-->
<!--            spring会通过反射调用对象的set方法完成属性的赋值&ndash;&gt;-->
<!--      property:配置类的属性; ref:关联到具体的bean&ndash;&gt;-->
       <property name="helloService" ref="zhHelloService"></property>
       <property name="byeService" ref="zByeService"></property>
    </bean>

2) 构造器注入:类中定义带属性参数的构造方法,在bean中配置<constructor-arg> 配置构造器;

<!--开启注解,配置扫描包,spring会在对应的包下去扫描配置了注解的类-->
<context:component-scan base-package="before,spring,aop"></context:component-scan>

<bean id="userAction" class="spring.UserAction">
<!-- 构造器注入,index指定下标 从0开始,type 指定类型-->
<constructor-arg index="0" ref="zhHelloService"></constructor-arg>
<constructor-arg index="1" ref="eByeService"></constructor-arg>
</bean>
    public UserAction() {
        
    }
    //构造器注入,需要创建有参构造方法
    public UserAction(HelloService helloService) {
        this.helloService = helloService;
    }

3) 注解注入:在spring配置文件中指定开启注解,并在对应的类上添加注解。常用注解有:
a.扫描bean的注解。相当于在xml中定义<bean>标签
        a)@Controller:用于控制层的注解。(整合Struts2/springmvc时,用来标注控制层类)

@Controller("a")  //<bean class="spring.UserAction">

        b)@Service: 用于Service业务逻辑处理层的注解

@Service("zByeService")
public class ZByeService implements BbyeService {
    @Override
    public void sayBye() {
        System.out.println("你好呀");
    }
}

        c)@Repository: 用于Dao层注解
        d)@Component :用于其他组件

===============================重点,面试经常问的===================================
b.依赖注入的注解:写在属性上,或对应set方法上
       a)@Autowired:spring的注解,按照类型进行注入。

  //required:指定对象是否必须,为false,则可以为null(即使查找的对象不存在,也不会报错,只会报空指针异常),默认为true(如果找不到对象,就会报错,报找不到对象的错误)
    @Autowired(required = true)
    private HelloService helloService;

       b)@Resource:java提供的注解,默认根据名称注入(指定了name,则根据name,没指 定name,则根据属性名),没有对应名称则按照类型注入。

    //Resource(name):指定注入对象的名称(id),当一个接口有多个实现类的情况下
    //如果没有通过name指定注入的对象名,则会先根据属性名称进行注入,如果不存在对应的对象,则根据类型进行注入
    @Resource(name = "eByeService")
    //指定name,就按name来;不指定name,就按byeService(属性的名称)来,再找不到,就按BbyeService(类型)来;
    private BbyeService byeService;

       c)@Qualifier:配合@Autowired使用,指定注入对象的名称===>这两个配合使用起来就相当于@Resource;

    @Qualifier("zhHelloService")
    //required:指定对象是否必须,为false,则可以为null(即使查找的对象不存在,也不会报错,只会报空指针异常),默认为true(如果找不到对象,就会报错,报找不到对象的错误)
    @Autowired(required = true)
    private HelloService helloService;

=======================================================================================

c.其他注解
       a)@Scope 指定对象的作用域(创建方式和生命周期)
          i.单例(默认的)singletion

    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("/applicationContext2.xml");
        UserAction userAction1= (UserAction) applicationContext.getBean("a");
        UserAction userAction2= (UserAction) applicationContext.getBean("a");
        System.out.println(userAction1==userAction2);//true 说明是同一个对象,默认创建方式是单例
}

因为是单例模式,所有对象只创建一次,所有值也就相等;

          ii.Prototype:多实例(struts2)

@Scope("prototype")//指定为多实例

因为是多例模式,所以对象创建两次,值也就不相等了;

          iii.Request: bean的生命周期与request请求一致(springmvc)
          iv.Session:bean的生命周期与session一致(springmvc)
          v.Global Session: application
      b)@PostConstruct: 初始化方法 ==>init-method
      c)@PreDestory:销毁方法 ==>destory-method
      d)@Lazy: 懒加载注解,指定spring容器加载时不去创建该对象

@Lazy//延迟加载
posted @ 2020-05-21 22:43  等你的夏天  阅读(247)  评论(0编辑  收藏  举报