一、概述

所谓零配置,并不是说一点配置都没有了,而是配置很少而已。通过约定来减少需要配置的数量,提高开发效率。

零配置实现主要有以下两种方式:

  • 惯例优先原则:也称为约定大于配置(convention over configuration),即通过约定代码结构或命名规范来减少配置数量,但不会减少配置文件。
  • 基于注解的规约配置:通过在指定类上指定注解,约定其含义来减少配置数量,从而提高开发效率;如事务注解@Transaction是基于注解的规约,在指定的类或方法上使用该注解就表示其需要事务。

Spring基于注解的规约配置有三个层级:

  • Bean依赖注入:通过注解方式替代基于XML配置中的依赖注入,如使用@Autowired注解来完成依赖注入。
  • Bean定义:通过注解方式进行Bean配置元数据定义,从而完全将Bean配置元数据从配置文件中移除。
  • Java类替换配置文件:使用Java类来定义所有的Spring配置,完全消除XML配置文件

二、Bean依赖注入

1、开启注解支持

<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:annotation-config /> </beans>

2、@Autowired

@Autowired根据类型自动注入,可作用于字段、构造器、方法,提供required设置注入是否必须,默认为必须

public @interface Autowired {
boolean required() default true;
}

示例如下:

实体类

public class TestBean {
private String message1; // for: 字段注入
@Autowired
private String message2; // for: 静态字段不能注入
@Autowired
private static String message3; private String message4; // for: 泛型注入
@Autowired
private List<String> messages; // for: 泛型注入(指定具体类型)
@Autowired
private ArrayList<String> messages2; // for: 构造器注入
@Autowired
private TestBean(String msg) {
this.message1 = msg;
} public String getMessage1() {
return message1;
} public String getMessage2() {
return message2;
} public String getMessage3() {
return message3;
} public String getMessage4() {
return message4;
} // for: 方法注入
@Autowired
public void setMessage4(String message4) {
this.message4 = message4;
} public List<String> getMessages() {
return messages;
} public List<String> getMessages2() {
return messages2;
}
}

XML配置

<bean class="java.util.ArrayList">
<constructor-arg index="0">
<list value-type="java.lang.String">
<value>matt</value>
<value>pretty</value>
</list>
</constructor-arg>
</bean> <bean id="str" class="java.lang.String">
<constructor-arg index="0" value="kevin"/>
</bean> <bean class="cn.matt.noconfig.TestBean"></bean>

测试

@org.junit.Test
public void testAutowired() {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
TestBean testBean = context.getBean(TestBean.class);
System.out.println("构造器注入:" + testBean.getMessage1());
System.out.println("字段注入:" + testBean.getMessage2());
System.out.println("静态字段不能注入:" + testBean.getMessage3());
System.out.println("方法注入:" + testBean.getMessage4());
System.out.println("泛型注入:" + testBean.getMessages());
System.out.println("泛型注入(指定具体类型):" + testBean.getMessages2());
}
/*输出:
构造器注入:kevin
字段注入:kevin
静态字段不能注入:null
方法注入:kevin
泛型注入:[kevin]
泛型注入(指定具体类型):[matt, pretty]
*/

注意,@Autowired不支持静态字段注入;对于泛型的注入,须明确指定泛型的具体类型,详细如下:

  • 数组类型、集合(Set、Collection、List)接口类型:将根据泛型获取匹配的所有候选者并注入到数组或集合中,如“List<HelloApi> list”将选择所有的HelloApi类型Bean并注入到list中,而对于集合的具体类型将只选择一个候选者,“如 ArrayList<HelloApi> list”将选择一个类型为ArrayList的Bean注入,而不是选择所有的HelloApi类型Bean进行注入;
  • 字典(Map)接口类型:同样根据泛型信息注入,键必须为String类型的Bean名字,值根据泛型信息获取,如“Map<String, HelloApi> map” 将选择所有的HelloApi类型Bean并注入到map中,而对于具体字典类型如“HashMap<String, HelloApi> map”将只选择类型为HashMap的Bean注入,而不是选择所有的HelloApi类型Bean进行注入。

2、@Value

@Value注解用于注入SpEL表达式,可放置在字段、@Autowired注解的方法的参数上

示例如下:

实体类

public class TestBean2 {

    @Value("#{str}")
private String message1; private String message2; public String getMessage1() {
return this.message1;
} public String getMessage2() {
return message2;
} @Autowired
public void setMessage2(@Value("#{str}#{str}") String message2) {
this.message2 = message2;
}
}

XML配置:

<bean id="str" class="java.lang.String">
<constructor-arg index="0" value="kevin"/>
</bean> <bean class="cn.matt.noconfig.TestBean2"></bean>

测试:

@org.junit.Test
public void testValue() {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
TestBean2 testBean = context.getBean(TestBean2.class);
Assert.assertTrue(StringUtils.equals("kevin", testBean.getMessage1()));
Assert.assertTrue(StringUtils.equals("kevinkevin", testBean.getMessage2()));
}

3、@Qualifier

@Qualifier注解作为修饰符,与@Autowired一起使用,解决类型有多个实例时无法指定某一实例的问题

示例如下:

接口及其两个实现类

public interface Hello {
void saySomething();
}
//@Qualifier("abc")
@Component("abc")
public class HelloImpl1 implements Hello {
@Override
public void saySomething() {
System.out.println("HelloImpl1");
}
}
@Component
public class HelloImpl2 implements Hello {
@Override
public void saySomething() {
System.out.println("HelloImpl2");
}
}

XML配置

<context:component-scan base-package="cn.matt.noconfig"/>  

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-context.xml")
public class BaseSpringTest { }
public class SpringTest extends BaseSpringTest {
@Qualifier("abc")
@Autowired
private Hello hello; @Test
public void testHello() {
hello.saySomething();
}
}

说明:

  • @Qualifier可作用于类,用于指定修饰名
  • @Qualifier与@Autowired一起使用指定某一实例时,value可为修饰名(通过@Qualifier指定),也可为bean名(通过@componet指定)
  • 相对于bean名,@Qualifier指定的修饰名可重复,多个类可共用同一修饰名,较灵活,详细可参考 @Qualifier注解

4、@Resource

@Resource注解也是自动装配,默认根据类型装配,如果指定name属性将根据名字装配,只能作用于字段和方法

@Resource(name = "标识符")
字段或setter方法

5、@PostConstruct与@PreDestroy  

@PostConstruct与@PreDestroy用于指定初始化和销毁方法,与<bean>标签的init-method和destroy-method属性指定相同

@PostConstruct
public void init() {
System.out.println("==========init");
}
@PreDestroy
public void destroy() {
System.out.println("==========destroy");
}

参考:

第十二章 零配置 之 12.1 概述 ——跟我学spring3

第十二章 零配置 之 12.2 注解实现Bean依赖注入 ——跟我学spring3

Spring注解注入bean

@Qualifier注解

Spring 使用介绍(八)—— 零配置(一)的更多相关文章

  1. Parcel.js + Vue 2.x 极速零配置打包体验

    继 Browserify.Webpack 之后,又一款打包工具 Parcel 横空出世 Parcel.js 的官网有这样的自我介绍 “极速零配置Web应用打包工具” 简单接触了一下,单从效率上来说,确 ...

  2. Parcel + Vue 2.x 极速零配置打包体验

    继 Browserify.Webpack 之后,又一款打包工具 Parcel 横空出世 Parcel.js 的官网有这样的自我介绍 “极速零配置Web应用打包工具” 简单接触了一下,单从效率上来说,确 ...

  3. Spring 使用介绍(九)—— 零配置(二)

    三.Bean定义 1.开启bean定义注解支持 开启注解支持须添加以下配置项: <context:component-scan base-package="cn.matt"/ ...

  4. Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解(1) - 基本介绍

    Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解(1) - 基本介绍 spring集成 mybatis Spring4.x零配置框架搭建 两年前一直在做后 ...

  5. 基于纯Java代码的Spring容器和Web容器零配置的思考和实现(3) - 使用配置

    经过<基于纯Java代码的Spring容器和Web容器零配置的思考和实现(1) - 数据源与事务管理>和<基于纯Java代码的Spring容器和Web容器零配置的思考和实现(2) - ...

  6. Spring 基于注解零配置开发

    本文是转载文章,感觉比较好,如有侵权,请联系本人,我将及时删除. 原文网址:< Spring 基于注解零配置开发 > 一:搜索Bean 再也不用在XML文件里写什么配置信息了. Sprin ...

  7. Spring MVC 学习总结(八)——Spring MVC概要与环境配置(IDEA+Maven+Tomcat7+JDK8、示例与视频)

    一.MVC概要 MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范,用一种将业务逻辑.数据.显示分离的方法组织代码,MVC主要作用是降低了视图与业务 ...

  8. spring+hibernate+struts2零配置整合

    说句实话,很久都没使用SSH开发项目了,但是出于各种原因,再次记录一下整合方式,纯注解零配置. 一.前期准备工作 gradle配置文件: group 'com.bdqn.lyrk.ssh.study' ...

  9. Spring Web工程web.xml零配置即使用Java Config + Annotation

    摘要: 在Spring 3.0之前,我们工程中常用Bean都是通过XML形式的文件注解的,少了还可以,但是数量多,关系复杂到后期就很难维护了,所以在3.x之后Spring官方推荐使用Java Conf ...

随机推荐

  1. Maven项目pom.xml文件简单解析

    Maven项目pom.xml简单解析 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="h ...

  2. springcloud(十三):Eureka 2.X 停止开发,但注册中心还有更多选择:Consul 使用详解

    在上个月我们知道 Eureka 2.X 遇到困难停止开发了,但其实对国内的用户影响甚小,一方面国内大都使用的是 Eureka 1.X 系列,另一方面 Spring Cloud 支持很多服务发现的软件, ...

  3. 腾讯AlloyTeam正式发布omi-cli脚手架 - 创建网站无需任何配置

    omi-cli omi-cli omi-cli命令 omi框架 用户指南 文件目录 npm 脚本 npm start npm run dist 代码分割 兼容 IE8 插入 CSS 插入组件局部 CS ...

  4. vue 饿了么项目笔记

    vue 饿了么项目 1.图标字体引用 链接 2.scss 二三倍图切换 1像素边框 链接 3.better-scroll 4.布局 商品主页面 <div id="app"&g ...

  5. H5 35-背景平铺属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Python—函数的名称空间

    名称空间 又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方 名称空间共3种, ...

  7. 16-使用Selenium模拟浏览器抓取淘宝商品美食信息

    淘宝由于含有很多请求参数和加密参数,如果直接分析ajax会非常繁琐,selenium自动化测试工具可以驱动浏览器自动完成一些操作,如模拟点击.输入.下拉等,这样我们只需要关心操作而不需要关心后台发生了 ...

  8. Division and Union CodeForces - 1101C (排序后处理)

    There are nn segments [li,ri][li,ri] for 1≤i≤n1≤i≤n. You should divide all segments into two non-emp ...

  9. rbac权限+中间件

    1.权限组件rbac 1.什么是权限 1 项目与应用 2 什么是权限? 一个包含正则表达式url就是一个权限 who what how ---------->True or Flase 2.版本 ...

  10. Python之字符串格式化

    1)     占位符%s: %s是通用的占位符,所有类型不管是string还是int还是float全都代表. 如果使用%d,则只能代表整数:如果是%f,则只能代表小数: 2)     直接用加号+连接 ...