@Resource注解(javax.annotation.Resource;)由sun公司开发而成;@Resource注解默认按照输入的名称进行bean装配
@Autowired注解(org.springframework.beans.factory.annotation.Autowired)是spring的注解;@Autowired注解默认按照类型方式进行bean装配
Spring属于第三方的,J2EE是Java自己的东西。
现在我们有一个StudentDao接口:
public interface StudentDao {
public void add();
public void find();
}
另外加入两个实现类:
@Repository//被spring托管
public class StudentRedisDaoImpl implements StudentDao{
@Override
public void add() {
System.out.println("redis中的添加完成");
}
@Override
public void find() {
System.out.println("redis中的查询完成");
}
}
@Repository //<bean id="studentDaoImpl" class="../">
public class studentDaoImpl implements StudentDao{
@Override
public void add() {
System.out.println("访问数据库,完成添加功能");
}
@Override
public void find() {
System.out.println("访问数据库,完成查找功能");
}
}
主调类:
@Service
public class StudentBizImpl implements StudentBiz{
// private StudentDao dao = new studentDaoImpl();
//缺点:1 StudentBizImpl是直接依赖于studentDaoImpl
//根据类型注入的!!!!!!!!!!!!
@Autowired //<property name="studentDao" ref="studentDaoImpl"> 完成自动装配的工作, 通过 @Autowired的使用来消除 set ,get方法
private StudentDao studentDao ;//StudentDao接口
@Override
public void add() {
studentDao.add();
}
@Override
public void find() {
studentDao.find();
}
public void setStudentDao(StudentDao dao) {
this.studentDao = dao;
System.out.println("spring调用set方法完成注入studentDao对象");
}
}
如果我们这样运行,会抛出异常:
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:88)
at com.syy.springtest.testAnnotation.AppTest.testHello4(AppTest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.syy.dao.StudentDao' available: expected single matching bean but found 2: studentRedisDaoImpl,studentDaoImpl
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:215)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:584)
... 37 more
意思是在装配bean时,发现了两个相同的实现类,都implementsStudentDao, 因此不知道选择哪一个,抛出异常。
这时,我们需要再加一个注解@Qualifier("studentRedisDaoImpl") ,这样就只针对 studentRedisDaoImpl 这个类
但如果用@Resource注解,我们会发现方便了许多,@Resource(name="studentRedisDaoImpl") 就可以实现@Resource注入,并且使用@Resource可以减少代码和Spring之间的耦合。