Spring入门篇 学习笔记

@Required

@Required 注解适用于 bean 属性的 setter 方法

这个注解仅仅表示,受影响的 bean 属性必须在配置时被填充,通过在 bean 定义或通过自动装配一个明确的属性值:

public class SimpleMovieLister{
private MovieFinder movieFinder; @Required
public void SetMovieFinder(MovieFinder movieFinder){
this.movieFinder = movieFinder;
}
}

@Required 使用比较少,一般使用 @Autowired

@Autowired: setter, 构造器, 成员变量自动注入

可以将 @Autowired 理解为“传统”的 setter 方法:

public class SimpleMovieLister{
private MovieFinder movieFinder; @Autowired
public void SetMovieFinder(MovieFinder movieFinder){
this.movieFinder = movieFinder;
}
}

可用于构造器或成员变量:

@Autowired
private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao){
this.customerPreferenceDao = customerPreferenceDao;
}

默认情况下,如果因找不到合适的 bean 将会导致 autowiring 失败抛出异常,可以通过下面的方式避免:

public class SimpleMovieLister{
private MovieFinder movieFinder; @Autowired(required=false)
public void SetMovieFinder(MovieFinder movieFinder){
this.movieFinder = movieFinder;
}
}
  • 每个类只能有一个构造器被标记为 required=true
  • @Autowired 的必要属性,建议使用 @Required 注解

示例

添加类:

public interface InjectionDAO {

	void save(String arg);

}

@Repository
public class InjectionDAOImpl implements InjectionDAO { public void save(String arg) {
//模拟数据库保存操作
System.out.println("保存数据:" + arg);
} } public interface InjectionService { void save(String arg); } @Service
public class InjectionServiceImpl implements InjectionService { // @Autowired
private InjectionDAO injectionDAO; // @Autowired
public void setInjectionDAO(InjectionDAO injectionDAO) {
this.injectionDAO = injectionDAO;
} @Autowired
public InjectionServiceImpl(InjectionDAO injectionDAO) {
this.injectionDAO = injectionDAO;
} public void save(String arg) {
//模拟业务操作
System.out.println("Service(Property)接收参数:" + arg);
arg = arg + ":" + this.hashCode();
injectionDAO.save(arg);
} }

添加测试类:

@RunWith(BlockJUnit4ClassRunner.class)
public class TestInjection extends UnitTestBase { public TestInjection(){
super("classpath:spring-beanannotation.xml");
} @Test
public void testAutowired(){
InjectionService service = super.getBean("injectionServiceImpl"); service.save("This is autowired.");
} }

@Autowired: 数组, Map 自动注入

可以使用 @Autowired 注解那些众所周知的解析依赖性接口,比如:BeanFactory, ApplicationContext, Environment, ResourceLoader, ApplicationEventPublisher, MessageSource

public class MovieRecommender{

	@Autowired
private ApplicationContext context; public MovieRecommender(){
}
}

可以通过添加注解给需要该类型的数组的字段或方法,以提供 ApplicationContext 中的所有特定类型的 bean

private Set<MovieCatalog> movieCatalog;

@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs){
this.movieCatalogs = movieCatalogs;
}

可以用于装配 key 为 String 的 Map

private Map<String, MovieCatalog> movieCatalogs;

@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs){
this.movieCatalogs = movieCatalogs;
}

如果希望数组有序,可以让 bean 实现 org.springframework.core.Ordered 接口或使用 @Order注解

@Autowired 是由 BeanPostProcessor 处理的,所以不能在自己的 BeanPostProcessor 或 BeanFactoryPostProcessor 类型应用这些注解,这些类型必须通过 XML 或者 @Bean 注解加载

示例

新建类:

public interface BeanInterface {

}

@Order(value = 2)
@Component
public class BeanImplOne implements BeanInterface { } @Order(value = 1)
@Component
public class BeanImplTwo implements BeanInterface { } @Component
public class BeanInvoker { @Autowired
private List<BeanInterface> list; @Autowired
private Map<String, BeanInterface> map; public void say() {
if (null != list && 0 != list.size()) {
System.out.println("list...");
for (BeanInterface bean : list) {
System.out.println(bean.getClass().getName());
}
} else {
System.out.println("List<BeanInterface> list is null !!!!!!!!!!");
} System.out.println(); if (null != map && 0 != map.size()) {
System.out.println("map...");
for (Map.Entry<String, BeanInterface> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue().getClass().getName());
}
} else {
System.out.println("Map<String, BeanInterface> map is null !!!!!!!!!!");
} } }

在 TestInjection 中添加测试方法:

@Test
public void testMultiBean(){
BeanInvoker invoker = super.getBean("beanInvoker");
invoker.say();
}

@Qualifier

按类型自动装配可能多个 bean 实例的情况,可以使用 @Qualifier 注解缩小范围(或指定唯一),也可以用于指定单独的构造器参数或方法参数

可用于注解集合类型变量

public class MovieRecommender{

    @Autowired
@Qualifier("main")
private MovieCatalog movieCatalog;
} public class MovieRecommender{
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao; @Autowired
public void prepare(@Qualifier("main")MovieCatalog movieCatalog
, CustomerPreferenceDao customerPreferenceDao){
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
}

在 XML 文件中实现 Qualifier:

<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" > <context:annotation-config /> <bean class="example.SimpleMovieCatalog">
<qualifier value="main"/>
</bean> <bean class="example.SimpleMovieCatalog">
<qualifier value="action"/>
</bean> <bean id="movieRecommender" class="example.MovieRecommender" /> </beans>

如果通过名字进行注解注入,主要使用的不是 @Autowired (即使在技术上能够通过 @Qualifier 指定 bean 的名字),替代方式是使用 JSR-250 @Resource 注解,它是通过其独特的名称定义来识别特定的目标(这是一个与所声明的类型无关的匹配过程)

因语义差异,集合或 Map 类型的 bean 无法通过 @Autowired 来注入时,因为没有类型匹配到这样的 bean,为这些 bean 使用 @Resource 注解,通过唯一名称引用集合或 Map 的 bean

@Autowired 适用于 fields, constructors, multi-argument methods 这些允许在参数级别使用 @Qualifier 注解缩小范围的情况

@Resource 适用于成员变量、只有一个参数的 setter 方法,所以在目标时构造器或一个多参数方法时,最好的方式时使用 @Qualifier

可以定义自己的 qualifier 注解:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre{
String value();
} public class MovieRecommender{
@Autowired
@Genre("Action")
private MovieCatalog actionCatalog;
private MovieCatalog comedyCatalog; @Autowired
public void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog){
this.comedyCatalog = comedyCatalog;
} }

示例

修改 BeanInvoker:

@Component
public class BeanInvoker { @Autowired
private List<BeanInterface> list; @Autowired
private Map<String, BeanInterface> map; @Autowired
@Qualifier("beanImplTwo")
private BeanInterface beanInterface; public void say() {
if (null != list && 0 != list.size()) {
System.out.println("list...");
for (BeanInterface bean : list) {
System.out.println(bean.getClass().getName());
}
} else {
System.out.println("List<BeanInterface> list is null !!!!!!!!!!");
} System.out.println(); if (null != map && 0 != map.size()) {
System.out.println("map...");
for (Map.Entry<String, BeanInterface> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue().getClass().getName());
}
} else {
System.out.println("Map<String, BeanInterface> map is null !!!!!!!!!!");
} System.out.println(); if (null != beanInterface) {
System.out.println(beanInterface.getClass().getName());
} else {
System.out.println("beanInterface is null...");
} } }

源码:learning-spring

学习 Spring (九) 注解之 @Required, @Autowired, @Qualifier的更多相关文章

  1. Spring 学习——Spring常用注解——@Component、@Scope、@Repository、@Service、@Controller、@Required、@Autowired、@Qualifier、@Configuration、@ImportResource、@Value

    Bean管理注解实现 Classpath扫描与组件管理 类的自动检测与注册Bean 类的注解@Component.@Service等作用是将这个实例自动装配到Bean容器中管理 而类似于@Autowi ...

  2. 学习 Spring (十) 注解之 @Bean, @ImportResource, @Value

    Spring入门篇 学习笔记 @Bean @Bean 标识一个用于配置和初始化一个由 Spring IoC 容器管理的新对象的方法,类似于 XML 配置文件的 可以在 Spring 的 @Config ...

  3. mybatis源码学习--spring+mybatis注解方式为什么mybatis的dao接口不需要实现类

    相信大家在刚开始学习mybatis注解方式,或者spring+mybatis注解方式的时候,一定会有一个疑问,为什么mybatis的dao接口只需要一个接口,不需要实现类,就可以正常使用,笔者最开始的 ...

  4. Spring 学习——Spring JSR注解——@Resoure、@PostConstruct、@PreDestroy、@Inject、@Named

    JSR 定义:JSR是Java Specification Requests的缩写,意思是Java 规范提案.是指向JCP(Java Community Process)提出新增一个标准化技术规范的正 ...

  5. spring注入注解@Resource和@Autowired

    一.@Autowired和@Qualifier @Autowired是自动注入的注解,写在属性.方法.构造方法上,会按照类型自动装配属性或参数.该注解,可以自动装配接口的实现类,但前提是spring容 ...

  6. 学习 Spring (十一) 注解之 Spring 对 JSR 支持

    Spring入门篇 学习笔记 @Resource Spring 还支持使用 JSR-250 中的 @Resource 注解的变量或 setter 方法 @Resource 有一个 name 属性,并且 ...

  7. 学习 Spring (八) 注解之 Bean 的定义及作用域

    Spring入门篇 学习笔记 Classpath 扫描与组件管理 从 Spring 3.0 开始,Spring JavaConfig 项目提供了很多特性,包括使用 java 而不是 XML 定义 be ...

  8. spring注入之使用标签 @Autowired @Qualifier

      使用标签的缺点在于必需要有源代码(由于标签必须放在源代码上),当我们并没有程序源代码的时候.我们仅仅有使用xml进行配置. 比如我们在xml中配置某个类的属性            <bea ...

  9. 菜鸟学习Spring——SpringMVC注解版前台向后台传值的两种方式

    一.概述. 在很多企业的开法中常常用到SpringMVC+Spring+Hibernate(mybatis)这样的架构,SpringMVC相当于Struts是页面到Contorller直接的交互的框架 ...

随机推荐

  1. pycharm2018.3版 永久激活

    pycharm2018.3版  永久激活 如需转发,请注明出处:小婷儿的python  https://www.cnblogs.com/xxtalhr/p/10258257.html 激活前准备工作 ...

  2. AJAX请求返回HTTP 400 错误 - 请求无效 (Bad request)

    在ajax请求后台数据时有时会报HTTP400错误-请求无效(Badrequest);出现这个请求无效报错说明请求没有进入到后台服务里: 原因: 1)前端提交数据的字段名称或者是字段类型和后台的实体类 ...

  3. Java多线程(三)—— synchronized关键字详解

    一.多线程的同步 1.为什么要引入同步机制 在多线程环境中,可能会有两个甚至更多的线程试图同时访问一个有限的资源.必须对这种潜在资源冲突进行预防. 解决方法:在线程使用一个资源时为其加锁即可. 访问资 ...

  4. 管理篇:测试Leader应该做哪些事

    基于前面的2篇分享:基础篇和进阶篇,这篇博客,整理了之前大佬的分享:作为一个测试leader,应该做那些事情... 一.负责测试组的工作组织和管理 1.参加软件产品开发前的需求调研和分析: 2.根据需 ...

  5. mysql安装与配置详情

    一.概述 MySQL版本:5.6.43 下载地址:mysql-installer-community-5.6.43.0,提取码:tgmk 客户端工具:NavicatforMySQL 下载地址:Navi ...

  6. java 一次CPU占用过高问题的排查及解决

    最近一段时间  某台服务器上的一个应用总是隔一段时间就自己挂掉      用top看了看  从重新部署应用开始没有多长时间CPU占用上升得很快 排查步骤 1.使用top 定位到占用CPU高的进程PID ...

  7. [故障公告]阿里云“华东1地域部分负载均衡https访问异常“引起部分站点无法访问

    今天上午 9:40 - 11:06 左右,由于阿里云“华东1地域部分负载均衡https访问异常”,造成我们的部分站点(尤其是博客后台)无法正常访问,给您带来了很大的麻烦,请您谅解. 现已恢复正常,如果 ...

  8. python3 pip 安装Scrapy在win10 安装报错error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

    问题描述 当前环境win10,python_3.6.1,64位. 在windows下,在dos中运行pip install Scrapy报错: building 'twisted.test.raise ...

  9. 01-JavaScript介绍

    JavaScript价绍 1.引言 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) ...

  10. Django之用户上传文件的参数配置

    Django之用户上传文件的参数配置 models.py文件 class Xxoo(models.Model): title = models.CharField(max_length=128) # ...