Spring依赖注入

Spring的依赖注入

Spring中有几种依赖注入的方式?

从大的范围来说就是:手动注入和自动注入

手动注入

手动注入是我们最开始学习spring的时候使用的,因为对于初学者来说那更容易理解。

set注入
<bean name="userService" class="com.qijian.service.UserService">
  <property name="orderService" ref="orderService"/>
</bean>
构造方法注入
<bean name="userService" class="com.qijian.service.UserService">
  <constructor‐arg index="0" ref="orderService"/>
</bean>
使用命名空间注入

c名命空间和p名命空间不能直接使用需要导入xml约束。

@Data
public class User {
    private String name;
    private int age;
}

C:xmlns:c="http://www.springframework.org/schema/c"

<bean id="user1" class="com.qijian.pojo.User" c:name="qijianc" c:age="18"/>

P:xmlns:p="http://www.springframework.org/schema/p"

<bean id="user" class="com.qijian.pojo.User"
              p:name="qijian"
              p:age="18"
        />
自动注入
xml的autowire自动注入

在xml中,可以定义一个Bean时去指定这个bean的自动注入模式

byType,byName,constructor,default,no

<bean id="userService" class="com.luban.service.UserService" autowire="byType"/>

表示Spring会自动的给userService中所有的属性自动赋值(不需要这个属性上有
@Autowired注解,但需要这个属性有对应的set方法)。

Spring在通过byName的自动填充属性时流程是:

​ 找到所有set方法所对应的XXX部分的名字

​ 根据XXX部分的名字去获取bean

Spring在通过byType的自动填充属性时流程是:

​ 获取到set方法中的唯一参数的参数类型,并且根据该类型去容器中获取bean

​ 如果找到多个,会报错。

Spring在通过constructor的自动填充(假设只有一个构造方法
	此时就可以不写set方法了,当某个bean是通过构造方法来注入时,spring利用

构造方法的参数信息从Spring容器中去找bean,找到bean之后作为参数传给构造方法,从而实例化得到一个bean对象,并完成属性赋值(属性赋值的代码得程序员来写)。

其他

no,表示关闭autowire

default,表示默认值,我们一直演示的某个bean的autowire,而也可以直接在标签中设置autowire,如果设置了,那么标签中设置的autowire如果为default,那么则会用标签中设置的autowire。

注意:XML中的autowire控制的是整个bean的所有属性,而@Autowired注解是直接写在某个属性、某个set方法、某个构造方法上的。

@Autowired注解相当于XML中的autowire属性的注解方式的替代。

从本质上讲,@Autowired注解提供了与autowire相同的功能,但是拥有更细粒度的控制和更广泛的适用性。

为什么我们平时都是用的@Autowired注解呢?而没有用上文说的这种自动注入方式呢?

@Autowired是更细粒度的控制(XML中的autowire控制的是整个bean的所有属性,而@Autowired注解是直接写在某个属性、某个set方法、某个构造方法上的。)

如果一个类有多个构造方法,那么如果用XML的autowire=constructor,你无法控制到底用哪个构造方法,而你可以用@Autowired注解来直接指定你想用哪个构造方法。同时,用@Autowired注解,还可以控制,哪些属性想被自动注入,哪些属性不想,这也是细粒度的控制。但是@Autowired无法区分byType和byName,@Autowired是先byType,如果找到多个则byName。

@Autowired注解的自动注入

@Autowired注解可以写在:

  1. 属性上:先根据属性类型去找Bean,如果找到多个再根据属性名确定一个
  2. 构造方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定一个
  3. set方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定一个

为什么@Autowired不支持静态字段或属性的注入?

@Component
@Scope("prototype")
public class OrderService {
}
@Component
@Scope("prototype")
public class UserService  {
  @Autowired
  private static OrderService orderService;
  public void test() {
    System.out.println("test123");
  }
}

UserService和OrderService都是原型Bean,假设Spring支持static字段进行自动注
入,那么现在调用两次

UserService userService1 = context.getBean("userService")

UserService userService2 = context.getBean("userService")

问此时,userService1的orderService值是什么?还是它自己注入的值吗?
答案是不是,一旦userService2 创建好了之后,static orderService字段的值就发生了修改了,从而出现bug。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值