Spring的bean注入的一些理解

对于spring,刚刚学习的,所以有很多都不是很理解,大多数都是只知道要这样做,但是不知道为什么要这样做。
在测试dao层操作的时候,写了一个TestStudentServiceImpl类,field有个private 的 StudentServiceImpl类,需要用spring注入,StudentServiceImpl继承了BaseDaoSupport<Student>类和实现了IStudentService接口。
测试类的代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
@TestExecutionListeners(
{ DependencyInjectionTestExecutionListener.class })
public class TestStudentService {
private StudentServiceImpl studentServiceImpl;

private SessionFactory sessionFactory;

@Test
public void testAddStudent(){
Student stu = new Student();
stu.setName("ligang");
studentServiceImpl.save(stu);
}

@Transient
public void testSessionFactory(){
Student stu = new Student();
stu.setName("yao");
stu.setPassword("123456");
Session sess =sessionFactory.openSession();
sess.save(stu);
}

@Resource(name="studentServiceImpl")
public void setStudentServiceImpl(StudentServiceImpl ssi){
this.studentServiceImpl = ssi;
}
}

applicationContext.xml里的一个片段

<bean id="studentServiceImpl" class="com.lin.service.impl.StudentServiceImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

运行的时候出现了下面的错误,于是查阅了一整的天资料,大概知道些spring在注入bean中好似使用了AOP框架产生代理,产生代理的方式有两种,第一种是实现了接口的类,会使用默认的jdk产生,该方式通过实现目标类的接口,产生一个aop代理类,该aop代理类可能封装了些事务处理,和目标类的方法,所以我们在拿出这个studentServiceImpl 这个bean的时候,其实是这个aop代理,当我们在测试类取出的时候,我们要求注入StudentServiceImpl类,aop代理却不是StudentServiceImpl类,只是和目标类实现了同样的IStudentService接口,所以我们在Test类中,应该使用接口来解决,即将在Test类要求注入的StudentServiceImpl,改为接口IStudentService.
[quote]
Bean named 'studentServiceImpl' must be of type [com.lin.service.impl.StudentServiceImpl], but was actually of type [$Proxy20]
[/quote]
改之后的Test类代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
@TestExecutionListeners(
{ DependencyInjectionTestExecutionListener.class })
public class TestStudentService {
private IStudentService studentServiceImpl;

private SessionFactory sessionFactory;

@Test
public void testAddStudent(){
Student stu = new Student();
stu.setName("ligang");
studentServiceImpl.save(stu);
}

@Transient
public void testSessionFactory(){
Student stu = new Student();
stu.setName("yao");
stu.setPassword("123456");
Session sess =sessionFactory.openSession();
sess.save(stu);
}

@Resource(name="studentServiceImpl")
public void setStudentServiceImpl(IStudentService ssi){
this.studentServiceImpl = ssi;
}
}

如果目标类没有实现任何接口,将采用第二种的产生代理的方法是CGLIB的字节码生成,该方式是通过产生目标类的子类,产生一个aop代理类,该类也封装了一些事务和目标类的方法,当我们取出的时候,其实也是aop代理类,只不过是目标类的子类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值