Spring注解注入 您所在的位置:网站首页 spring注解注入map Spring注解注入

Spring注解注入

#Spring注解注入| 来源: 网络整理| 查看: 265

Spring基于Annotation配置Bean 简介

这种注入方式也比较常见,并且在Spring企业级开发中用途最广的DI模式之一,有时候相对于XML配置模式,Autowire注入是很方便的。 首先需要导入支持AOP的包,因为需要在XML配置文件中通知Spring容器扫描含有注解文件的包。

分类

1)@Component 可以使用此注解描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。 2)@Repository 用于将数据访问层(DAO层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 3)@Service 通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 4)@Controller 通常作用在控制层(如 Struts2 的 Action),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。 5)@Autowired 用于对 Bean 的属性变量、属性的 Set 方法及构造函数进行标注,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。 6)@Resource 其作用与 Autowired 一样。其区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配。

@Resource 中有两个重要属性:name 和 type。

Spring 将 name 属性解析为 Bean 实例名称,type 属性解析为 Bean 实例类型。如果指定 name 属性,则按实例名称进行装配;如果指定 type 属性,则按 Bean 类型进行装配。

如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。 7)@Qualifier 与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。

案例

1)Dao层实现类

@Repository("userDao") // 持久层组件注解 public class UserDaoImpl implements UserDao { @Override public void add() { System.out.println("Dao层的add()方法。。。"); } }

2)Service层实现类

@Service("userService") public class UserServiceImpl implements UserService { @Resource(name = "userDao") private UserDao userDao; // public void setUserDao(UserDao userDao) { // this.userDao = userDao; // } @Override public void add() { userDao.add(); System.out.println("Service层的add()方法。。。"); } }

3)Annotation层

@Controller("userAction") public class UserAction { @Resource(name = "userService") private UserService userService; // public void setUserService(UserService userService) { // this.userService = userService; // } public void add(){ userService.add(); System.out.println("Action层的add()方法。。。"); } }

4)XML配置文件

5)测试类

public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserAction userAction = (UserAction) context.getBean("userAction"); userAction.add(); }

打印结果:

Dao层的add()方法。。。 Service层的add()方法。。。 Action层的add()方法。。。

上面案例使用的就是通过注解来实现注入bean。其中可以发现Service层、Annotation层的实现类中由属性,但是setter方法注释了也能注入成功,说明注解方法实现的注入,可以不用写setter方法,Spring容器会自动的帮我们实现注入。

将Service层的@Resource(name = "userService")改为@Resource(name = "userService1"),运行会报错,由此发现,使用@Resoure默认按照byName模式进行注入。改为@Autowired,并更改Service的属性名:private UserDao userDao;改为private UserDao userDao1;,运行通过并有正确结果,说明@Autowired注解默认按照byType模式进行注入。

@Qualifier注解的作用: 简单来说就是使用了@Autowired注解,但是此时出现了使用同一接口的多个实现类,此时由于默认使用的是byType模式,Spring并不知道我们需要注入的是什么,使用我们可以用@Qualifier调用byName模式告诉Spring我们需要注入那个bean。

注解注入之构造函数

在注解注入这块除了Setter注解注入,成员变量注解注入,还有一个比较重要的——“构造函数注入”。

其实也很简单理解,就是在构造方法上面写@Autowired即可,但是在学习的时候,碰到一个问题,就是一个有参构造函数中有多个同一类型形参,这个时候Spring就无法分辨我们实参的传递和赋值。 这个问题也想了好久,找了也蛮久的,因为这个问题是我临时想的,所以无从下手,一开始尝试使用@Qualifier解决问题,因为可以根据byName模式注入嘛,但是放在构造方法上面又报错,用@Resource也报错,就开始漫长的百度之旅,终于让我找到了一个很小很小的例子,@Qualifier注解放入构造函数的形参前面,运行,发现能够正确的Run出结果,后面仔细一想,发现我们的问题本质是Spring无法识别我们实参的传递和赋值,使用@Qualifier是正确的思路,主要是放置位置是在形参前面,来指明该形参使用的是byName模式并指明使用的BeanName,这样一来就能够理解了这一个特殊情况的解决问题方法。

代码如下:

@Controller("userAction") public class UserAction { private UserService userService1; private UserService userService2; @Autowired public UserAction(@Qualifier("userService") UserService userService1, @Qualifier("userService1")UserService userService2) { this.userService1 = userService1; this.userService2 = userService2; } public void add(){ userService1.add(); userService2.add(); System.out.println("Action层的add()方法。。。"); } }

在初学者应该会碰到这个问题,这个问题也是我在学习注解注入的构造方法的时候临时想到的!如果没有出现同类型的多参构造函数,一般情况下不需要使用@Qualifier

小结

实际上,我们使用注解来帮助我们注入时,是Spring帮助我们节省了代码,实现了操作,原理依旧是咱们写在XML配置文件中的一样,需要注意的就是@Autowired和@Repository注解默认使用的Autowire注入模式不同。还有就是在构造方法中@Autowired和@Qualifier的搭配使用

1.强制性的依赖性或者当目标不可变时,使用构造函数注入(应该说尽量都使用构造器来注入) 2.可选或多变的依赖使用setter注入(建议可以使用构造器结合setter的方式来注入) 3.在大多数的情况下避免field域注入(感觉大多数同学可能会有异议,毕竟这个方式写起来非常简便,但是它的弊端确实远大于这些优点)

会加油学习Java的,目前水平还不够,基础不扎实。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有