验证中...
开源中国 2018 年度最后一场技术盛会邀你来约~错过就要等明年啦!点此立即预约
@Resource与@Autowired注解
原始数据 复制代码
@Resource与@Autowired注解在一般使用情况下,它们的使用效果是一致的,但是相对而言,@Resource注解的功能更加强悍,@Resource可以根据名称进行指派。
· 如果在Spring的配置文件中,注入一个新的Bean,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="cn.mldn.mldnspring"/> <!-- 定义扫描包 -->
<bean id="newDeptDAOImpl" class="cn.springdemo.dao.impl.DeptDAOImpl"/>
</beans>
· 同样在相应的dao子类上,采用注解的方式进行注入,如下所示:
public interface IDeptDAO {
public boolean doCreate(Dept vo) ;
}
@Repository
public class DeptDAOImpl implements IDeptDAO {
@Override
public boolean doCreate(Dept vo) {
System.err.println("数据层-----" + vo);
return true;
}
}
@Repository等价于在配置文件上注入如下bean:
<bean id="deptDAOImpl" class="cn.springdemo.dao.impl.DeptDAOImpl"/>
业务层以及测试类如下:
业务层:
public interface IDeptService {
public boolean add(Dept vo) ;
}
@Service
public class DeptServiceImpl implements IDeptService {
@Autowired
private IDeptDAO deptDAO ; // 自动根据类型注入
@Override
public boolean add(Dept vo) {
return this.deptDAO.doCreate(vo);
}
}
测试类:
@ContextConfiguration(locations= {"classpath:spring/spring-base.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class TestDeptService {
@Autowired
public void setDeptService(IDeptService deptService) {
this.deptService = deptService;
}
@Test
public void testAdd() {
Dept vo = new Dept() ;
vo.setDeptno(99L);
vo.setDname("开发部");
System.out.println(this.deptService.add(vo));
}
}
vo类:
public class Dept implements Serializable {
private Long deptno ;
private String dname ;
public Dept() {
System.out.println("*************** 实例化Dept类对象 ***************");
}
public Long getDeptno() {
return deptno;
}
public void setDeptno(Long deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
@Override
public String toString() {
return "【" + super.toString() + "】deptno = " + this.deptno + "、dname = " + this.dname;
}
}
此时允许Junit测试程序,发现如下错误:
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'cn.springdemo.dao.IDeptDAO' available:
expected single matching bean but found 2: deptDAOImpl,newDeptDAOImpl
而如果此时将注入类型的名称变为相应的,如下所示:
@Service
public class DeptServiceImpl implements IDeptService {
@Autowired
private IDeptDAO deptDAOImpl ; // 自动根据类型注入
@Override
public boolean add(Dept vo) {
return this.deptDAOImpl.doCreate(vo);
}
}
此时Junit程序运行正常。因为名称匹配(默认使用注解,给出的bean的id将类的首字母变为小写,其他照常)可以自动根据byName匹配,而如果名称不匹配的时候会根据byType注入,
而当byType的时候就会发现两个同样类型的bean对象存在,自然就会出现如上的错误提示,而@Resource也有byName与byType的支持。
*************** 实例化Dept类对象 ***************
【数据层】【cn.springdemo.vo.Dept@6e0dec4a】deptno = 99、dname = 开发部
true
但是@Resource的支持更加的强大,@Resource可以在注入的时候指定具体的bean的名称。如下所示:
@Service
public class DeptServiceImpl implements IDeptService {
@Resource(name="deptDAOImpl")
private IDeptDAO deptDAO ; // 自动根据类型注入
@Override
public boolean add(Dept vo) {
return this.deptDAO.doCreate(vo);
}
}
此时代码正常运行。
虽然@Autowired无法直接指定具体bean的名称,但是在Spring中提供了另外的一个注解@Qualified来辅助它实现bean名称的配置。
@Service
public class DeptServiceImpl implements IDeptService {
@Autowired
@Qualifier("deptDAOImpl")
private IDeptDAO deptDAO ; // 自动根据类型注入
@Override
public boolean add(Dept vo) {
return this.deptDAO.doCreate(vo);
}
}
所示可以从以上得出如下的结论:
① @Resource注解是由JavaEE标准定义的资源注入,@Autowired是Spring自己定义的。
② 在使用的时候@Resource和@Autowired都具有ByName和ByType的支持。
③ @Resource可以利用name的属性进行指定bean的注入。如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。
如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
④ @Autowired本身没有指定bean的注入支持,但是Spring提供了@Qualifier注解来辅助它的功能,但是相对于@Resource来说比较麻烦一点。
⑤ @Autowired默认按照ByType匹配方式在容器中查找匹配的Bean,而@Resources默认按照ByName匹配方式在容器中查找匹配的Bean。
⑥ 除此之外,在JavaEE标准之中还提供有@Inject注解,功能与上面两者类似。@Inject和@Autowired一样也是默认按照ByType匹配方式在容器中查找匹配的Bean,
但是它没有require属性,不能对找不到对应的bean的异常做关闭的操作。

评论列表( 0 )

你可以在登录后,发表评论

搜索帮助