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. PAT A1055 The World's Richest (25 分)——排序

    Forbes magazine publishes every year its list of billionaires based on the annual ranking of the wor ...

  2. 简述DDOS攻击的工作原理

    1.DDOS攻击:大量的肉鸡对服务器的不同端口发送巨型流量的UDP报文,无法通关关闭端口的方式来进行隔离,破坏力极强,严重会造成服务器当机. SYN/ACK Flood攻击:经典最有效的DDOS方法. ...

  3. 用 Django 管理现有数据库

    在多数项目中,总有一些几乎一成不变的 CRUD 操作,编写这些代码很无聊,但又是整个系统必不可少的功能之一.我们在上一个项目中也面临类似的问题,虽然已经实现了一个功能相对完整的管理后台,也尽量做到了代 ...

  4. 搭建SpringBoot+dubbo+zookeeper+maven框架(三)

    今天我们要在原来搭建的框架基础上集成redis数据库. redis是Nosql数据库中使用较为广泛的非关系型内存数据库,redis内部是一个key-value存储系统.它支持存储的value类型相对更 ...

  5. java基础 容器 API

  6. bootstrap 失效的原因

    首先必须对着官方文档的模板来写: https://getbootstrap.com/docs/4.3/getting-started/introduction/ 然后: 这里必须加上 rel=&quo ...

  7. Sql 调优总结

    1前言 Sql 语句调优对应用性能非常重要,看了几篇文章,总结了一下数据库优化的方法. 2 数据库 Sql 优化 1 对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by ...

  8. Redux与它的中间件:redux-thunk,redux-actions,redux-promise,redux-saga

    序言 这里要讲的就是一个Redux在React中的应用问题,讲一讲Redux,react-redux,redux-thunk,redux-actions,redux-promise,redux-sag ...

  9. flask使用基础

    1.安装 pip install Flask 基本依赖库: jinja2:实现对模板的处理 werkzeug:本质是socket服务器,用于接收http请求,并对请求进行预处理,然后触发Flaks框架 ...

  10. vue特殊属性 key ref slot

    1.key 当使用key时,必须设置兄弟元素唯一的key,当key排列顺序变化时,兄弟元素会重新排列,而当key的值变化时,这个元素会被重新渲染. 有相同父元素的子元素必须有独特的 key.重复的 k ...