0
点赞
收藏
分享

微信扫一扫

spring 依赖注入深究

1、@Autowired这个注解,可以直接注解在私有成员变量上而不用去写setter方法。

 

2、Spring 在进行自动注入的时候(在B类中注入A的引用),首先需要用注解@Repository(或@Service)把A类声明成Spring bean,然后在B类中使用@Autowired注解把A的对象注入到B中。例如:

1)接口:

public interfaceBookmakerDao {
/**
*
*/
}

2) 接口实现类,并将该实现类声明成Spring bean:

@Repository
public classBookmakerDaoHibernate implements BookmakerDao {
/**
*
*/
}

3)依赖注入:

public classBookmakerDaoTest extends SpringTest {
@Autowired
//privateBookmakerDaoHibernate bookmakerDao; // 无法注入
private BookmakerDaobookmakerDao; // 成功注入

@Test
public void test() {
/**
*/
}
}

3、问题:为什么private BookmakerDaoHibernatebookmakerDao; // 无法注入?

1) Spring 在将声明的类创建成Spring bean时会进行一层代理,而动态代理的方式有两种:

  • 使用jdk的代理:这时该类必须要实现一个接口;
  • 使用cglib的代理:这时该类不需要实现接口;

 

2)上个例子中,由于类BookmakerDaoHibernate 实现了接口,所以Spring 看到@Repository后会优先使用jdk的代理来创建Spring bean,这种代理模式生成的代理对象依赖于目标对象的接口(目标对象必须有上级接口才可以使用jdk动态代理)。Spring在运行时使用自动代理将BookmakerDaoHibernate对象放在了一个代理对象的内部,所以当我们以为可以byClass注入的时候,却发现在Spring容器中无法找到这个BookmakerDaoHibernate类型的bean了。故,需要用接口来接收,才能正确注入。

 

3)如果上例中BookmakerDaoHibernate 没有实现接口,Spring 看到@Repository后会有限使用cglib的代理来创建Spring bean(项目中需要引入cglib库),这种代理模式生成的代理对象是目标对象的子类。故,可以被@Autowired根据父类名自动注入。


举报

相关推荐

0 条评论