【原文】https://www.toutiao.com/i6594205115605844493/
Spring学习Bean配置的三种方式(XML、注解、Java类)介绍与对比
本文将详细介绍Spring Bean配置的三种不同方式的特点与使用条件。
主要包括:
- 基于XML的配置方式
- 基于注解的配置方式
- 基于Java类的配置方式
一.基于XML的配置
请看Spring学习(十二)Spring 的配置文件概述
二.基于注解的配置
Spring2.0开始引入基于注解的配置方式,即Bean的定义信息可以通过在Bean的实现类上标注注解实现。
具体关于注解的知识请看Java注解(Annotation)介绍
@Component是Spring容器中的基本注解,表示容器中的一个组件(bean),可以作用在任何层次,下面的示例介绍该注解的使用方法。
注解配置示例:
- @Component("userDao")
- public class userDao{......}
他等效于XML配置
<bean id="userDao" class="cn.lovepi.***.userDao"/>
此外,还有一些其他的可以被用来注解bean的注解,这些可以让注解类本身的用途更加清晰,此外,特定的注解也具备特定的功能。
Spring在2.5后提供了一个context的命名空间,它提供了通过扫描类包来加载利用注解定义的Bean的方式。
在context中可以使用resource-pattern来过滤出特定的类。
<context:component-scan base-package="cn.lovepi.spring" resource-pattern="anno/*.class"/>
默认情况下加载的是package下的*.class即扫描全部类,在使用了resource-pattern之后,则只扫描package下的anno子包下的所有类。
不过使用resource-pattern并不能提供给我们完善的功能,所有我们得使用过滤子元素的方法。
- <context:component-scan base-package="cn.lovepi.spring">
- <context:include-filter type="regex" expression="cn.lovepi.spring.*"/>
- <context:exclude-filter type="aspectj" expression="cn.lovepi..*Controller+"/>
- </context:component-scan>
其中:
include-filter表示要包含的目标类,
exclude-filter表示要排除在外的目标类
一个component-scan标签下可以有多个include-filter和exclude-filter,
过滤表达式所支持的类型如下表所示:
在这些类型当中,除了Custom外,aspectj的过滤功能最强大,他能轻易的实现其他类别的过滤规则。
Spring3.0提供了一系列的针对依赖注入的注解,这使得Spring IoC在XML文件之外多了一种可行的选择,主要包含如下注解类型:
- Bean的定义注解
- Bean的生命周期注解
- Bean的依赖检查注解
- Bean的自动装配注解
1.Bean的定义注解
Spring自2.0开始,陆续引入了一些注解用于简化Spring的开发。
@Repository注解便属于最先引入的一批,用于将数据访问层(DAO层)的类标识为Spring Bean。具体使用如下:
①首先使用@Repository将DAO类声明为Bean
- @Repository
- public class UserDaoImpl implements UserDao{......}
②在XML配置文件中启动Spring的自动扫描功能
- <beans ...>
- <context:component-scan base-package="cn.lovepi.dao"/>
- ......
- <beans/>
如此的话,我们便不在需要在XML当中显式使用bean来进行bean的配置。Spring容器在初始化的时候便会自动扫描base-package所指定的包以及子包下面的所有class文件。所有标注为Repository的类将被自动注册为bean。
为什么Repository只能标注在DAO类上面呢?
因为该注解的作用不只是将类识别为bean,同时他还能将所标注的类中所抛出的数据访问异常封装为Spring的数据访问异常类型。Spring本身提供了一个丰富的,并且是与具体的访问技术无关的数据访问异常结构,用于封装不同的持久层框架所抛出的异常,使得异常独立与底层的框架。
Spring2.5在@Repository的基础上增加了功能类似的额外三个注解,总共有如下四种注解:
- @Component:一个泛化的概念,表示一个组件(Bean),可作用在任何层次
- @Controller:用于对Controller实现类进行标注,目前该功能与Component相同
- @Repository:用于对DAO实现类进行标注
- @Service:用于对Service实现类进行标注,目前该功能与Component相同
这三个注解除了作用于不同软件层次的类,其使用方式与Repository是完全相同的。
2.Bean的生命周期注解
在某些情况下,可能需要我们手工做一些额外的初始化或者销毁操作,例如资源的获取和是否操作,Spring1.x为此提供了两种方式供用户指定执行生命周期回调的方法:
- 实现Spring提供的两个接口:initializingBean 和 DisposableBean,这种方法是要求bean类实现Spring的接口,但增加了bean和Spring容器的耦合度,因此不推荐使用。
- 在XML文件中使用<bean>的init-method 和 destory-method 属性,指定初始化之后和回调之前的回调方法。这两个属性的取值是bean中相应的初始化和销毁方法的名称。方法名称任意,但是方法不能有参数。
示例如下:
- <bean id="userService" class="cn.lovepi.***.UserService"
- init-method="init" destory-method="destory">
- </bean>
在这里,我们指定了userService 这个bean的初始化方法为:init 销毁方法为:destory
Spring2.5在保留以上两种方式的基础上,提供了对JSR-250的支持。
JSR-250规范定义了两个用于指定声明周期方法的注解:
- @PostConstruct:初始化之后的执行的回调方法
- @PreDestroy:销毁之前的回调方法
注解示例说明:
- public class PersonService{
- @PostConstruct
- public void init(){......}
- @PreDestory
- public void destory(){......}
- }
在这里init方法是初始化之后执行的方法,而destory方法为销毁之前执行的方法
由于使用了注解,所以得激活Bean的后处理器,所以得在XML配置文件当中增加
<context:annotation-config/>
3.Bean的依赖检查注解
Spring2.0之前使用dependency-check在配置文件中设置属性用于依赖检查(只会检查Setter方法是否被调用),缺点是粒度较粗,该属性的取值包括以下几种:
- none: 默认不执行依赖检查
- simple :对原始基本类型和集合类型进行检查
- objects :对复杂类型进行检查
- all :对所有类型进行检查
使用Spring2.0提供的@Required注解,提供了更细粒度的控制,@Required注解只能标注在Setter方法之上,(标注在其他方法之上会被忽略 )用于检查其是否被调用,当Setter方法未被调用的话会抛出异常。
由于使用了注解,所以得激活Bean的后处理器,所以得在XML配置文件当中增加
<context:annotation-config/>
4.Bean的自动装配注解
@Autowired可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作,他根据类型进行自动装配,如果需要按名称进行装配,则需要配合@Qualifier使用。
当标注了@Autowired的方法所需的类型在Spring容器中不存在的话会抛出异常
- @Service
- public class LoginService{
- @Autowired
- private LogDao logDao;
- }
如上面的例子所示,假如Spring容器中没有LogDao这个bean的话便会抛出异常。
解决的办法便是使用required=false属性来标注
- public class LoginService{
- @Autowired(required=false)
- private LogDao LogDao;
- }
但是假如Spring当中存在多个所需类型的bean,那么便要使用@Qualifier注解来指定名称。
- public class LoginService{
- @Autowired
- @Qualifier("userDao")
- private UserDao userDao;
- }
@Autowired 可以对类中集合类的变量或方法入参进行标注,此时会将容器中类型匹配的所有Bean都注入进来,如下所示:
- public class loginService{
- @Autowired(required=false)
- public List<Plugin> pligins;
- public List<Plugin> getPlugins(){
- return plugins;
- }
- }
Spring会将容器中所有类型为Plugin的bean都注入到集合中去。
三.基于Java类的配置
基于Java类定义Bean配置元数据,其实就是通过Java类定义Spring配置元数据,且直接消除XML配置文件。
首先让我们看一下基于Java类如何定义Bean配置元数据,具体步骤如下:
- 使用@Configuration注解需要作为配置的类,表示该类将定义Bean的元数据
- 使用@Bean注解相应的方法,该方法名默认就是Bean的名称,该方法返回值就是Bean的对象。
- AnnotationConfigApplicationContext或子类进行加载基于java类的配置
接下来通过示例来演示下如何基于Java类来配置Spring
首先创建一个配置类
- @Configuration
- public class ApplicationContextConfig {
- @Bean
- public String message() {
- return "hello";
- }
- }<strong>
- </strong>
然后还需要一个测试类,来查看配置是否成功
- public class ConfigurationTest {
- public static void main(String[] args) {
- AnnotationConfigApplicationContext ctx =
- new AnnotationConfigApplicationContext(ApplicationContextConfig.class);
- System.out.println(ctx.getBean("message"));
- }
- }
通过@Configuration注解的类将被作为配置类使用,表示在该类中将定义Bean配置元数据,且使用@Configuration注解的类本身也是一个Bean,使用方式如下所示:
- @Configuration("ctxConfig")
- public class ApplicationContextConfig {
- ……
- }
其中Configuration中的参数值即为该bean的名称。
通过@Bean注解配置类中的相应方法,则该方法名默认就是Bean名,该方法返回值就是Bean对象,并定义了Spring IoC容器如何实例化、自动装配、初始化Bean逻辑,具体使用方法如下:
- @Bean(name={},
- autowire=Autowire.NO,
- initMethod="",
- destroyMethod="")
其中name为bean的名称,可以有多个,autowire为是否自动装配,默认值为NO,initMethod为bean的初始化方法,destoryMethod为bean的销毁方法。
bean的注解具体使用如下:
- @Bean
- public String message() {
- return new String("hello");
- }
如上的代码等价与XML配置:
- <bean id="message" class="java.lang.String">
- <constructor-arg index="0" value="hello"/>
- </bean>
注意:使用bean注解的方法不能是private、final、static的。
基于Java方式的配置方式不是为了完全替代基于XML方式的配置,两者可以结合使用,因此可以有两种结合使用方式:
- 在基于Java方式的配置类中引入基于XML方式的配置文件
- 在基于XML方式的配置文件中中引入基于Java方式的配置
引入基于XML配置文件:
- <bean id="message" class="java.lang.String">
- <constructor-arg index="0" value="test"></constructor-arg>
- </bean>
- @Configuration("ctxConfig")
- @ImportResource("classpath:com/jike/***/appCtx.xml")
- public class ApplicationContextConfig {
- ……
- }
可以看到在java程序中使用@ImportResource导入了XML的配置文件
引入基于Java的配置文件:
- <context:annotation-config/>
- <bean id="ctxConfig" class=“com.jike.***..ApplicationContextConfig"/>
- //测试类
- public void testXmlConfig() {
- String configLocations[] = {" classpath:com/jike/***/appCtx.xml"};
- ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);
- ……
- }
可以看到在XML的配置文件当中将java的配置类当中Bean来声明,第一行的是开启注解驱动支持。
值得注意的是必须得配置<context:annotation-config/>在XML配置文件中。
Spring提供了一个AnnotationConfigApplicanContext类,能够直接通过标注@Configuration的Java类启动Spring容器:
通过构造函数加载配置类:
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class);
通过编码方式注册配置类:
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.register(DaoConfig.class);
- ctx.register(ServiceConfig.class);
- ctx.refresh();
可以看到ctx注册了多个configuration类,然后通过refresh类来刷新容器以应用这些配置文件。
可以通过代码一个个的引入配置类,当然也可以使用@Import注解来引入配置类
引入多个配置类:
- @Configuration
- @Import(DaoConfig.class)
- public class ServiceConfig {……}
总结:不同配置方式比较
我们来看一下不同配置方式在不同方面的使用
其实Spring支持这么多的配置方式,那么这些配置方式必然有其自己独特的舞台
基于XML的配置主要使用场景:
- 第三方类库,如DataSource、JdbcTemplate等;
- 命名空间,如aop、context等;
基于注解的配置主要使用场景:
- Bean的实现类是当前项目开发的,可直接在Java类中使用注解配置
基于Java类的配置主要使用场景:
- 对于实例化Bean的逻辑比较复杂,则比较适合用基于Java类配置的方式
在日常的开发中我们主要是使用XML配置和注解配置方式向结合的开发方式,一般不推荐使用基于Java类的配置方式。
【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比的更多相关文章
-
Spring中bean实例化的三种方式
之前我已经有好几篇博客介绍Spring框架了,不过当时我们都是使用注解来完成注入的,具体小伙伴可以参考这几篇博客(Spring&SpringMVC框架案例).那么今天我想来说说如何通过xml配 ...
-
Spring学习(二)三种方式的依赖注入
1.前言 上一篇讲到第一个Spring项目的创建.以及bean的注入.当然.注入的方式一共有三种.本文将展开细说. 1.set注入:本质是通过set方法赋值 1.创建老师类和课程类 1.Course ...
-
spring配置datasource三种方式
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp34 spring配置datasource三种方式 1.使用org.spri ...
-
Spring bean管理器 bean实例化的三种方式
bean实例化的三种方式实现 第一种:使用类的无参数构造方法创建(常用 重要) 第一种实例化方式最常用,实例化类时会通过调用无参构造方法创建.示例代码如下: package spring.com.Us ...
-
spring中创建bean对象的三种方式以及作用范围
时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有 ...
-
【Spring】的【bean】管理(XML配置文件)【Bean实例化的三种方式】
Bean实例化的三种方式 说明:通过配置文件创建对象就称为Bean实例化. 第一种:使用类的无参构造创建(重点) 实体类 package com.tyzr.ioc; public class User ...
-
spring学习(03)之bean实例化的三种方式
bean实体例化的三种方式 在spring中有三中实例化bean的方式: 一.使用构造器实例化:(通常使用的一个方法,重点) 二.使用静态工厂方法实例化: 三.使用实例化工厂方法实例化 第一种.使用构 ...
-
spring配置datasource三种方式及具体信息
1.使用org.springframework.jdbc.datasource.DriverManagerDataSource说明:DriverManagerDataSource建立连接是只要有连接就 ...
-
spring配置datasource三种方式 数据库连接池
尊重原创(原文链接):http://blog.csdn.net/kunkun378263/article/details/8506355 1.使用org.springframework.jdbc.da ...
随机推荐
-
利用Flex组件birdeye绘制拓扑关系图
birdeye绘制拓扑关系图 1.flex简单介绍 Flex 是一个高效.免费的开源框架,可用于构建具有表现力的 Web应用程序,这些应用程序利用Adobe Flash Player和Adobe AI ...
-
sql server 自增长id 允许插入显示值
--允许插入显示插入主键id的值SET IDENTITY_INSERT [T0002_SType] ON 执行insert插入语句------------------ --关闭 插入显示值SET ID ...
-
安卓Design包之CollapsingToolbarLayout(可折叠的工具栏布局)的简单使用
转自: CollapsingToolbarLayout的使用 注意:使用前需要添加Design依赖包,使用toolbar时需要隐藏标题头 CollapsingToolbarLayout作用是提供了一个 ...
-
jquery升级换代
其实从去年开始1.9以上新版的jquery已不再支持toggle方法和live方法. live用on方法替代. 话说这个方法确实挺方便的,那么怎么交替点击呢,html的checked属性我觉得不是很好 ...
-
java它们的定义ArrayList序列, 大神跳跃
一个list有两种类型的对象,今天有需求必须责令不同的约会对象,这里是代码 /** *@author xh1991101@163.com */ List<Message> messages ...
-
h3c dhcp snooping
1. 组网需求Switch B通过以太网端口Ethernet1/1连接到DHCP服务器,通过以太网端口Ethernet1/2.Ethernet1/3连接到DHCP客户端.要求:l与DHCP服务器相连的 ...
-
kettle闪退问题
确定Java的配置环境没问题 kettle闪退的时候把spoon.bat里面的配置项改一下 if "%PENTAHO_DI_JAVA_OPTIONS%"=="" ...
-
基于HTML5 Canvas 点击添加 2D 3D 机柜模型
今天又返回好好地消化了一下我们的数据容器 DataModel,这里给新手做一个典型的数据模型事件处理的例子作为参考.这个例子看起来很简单,实际上结合了数据模型中非常重要的三个事件处理的部分:属性变化事 ...
-
ajax交互数据简单拼装,数组成字符串
json2Form:function(json) { var str = ""; for(var p in json){ // 判断对象是否为数组 if(typeof json[p ...
-
[Alpha阶段]第十一次Scrum Meeting
Scrum Meeting博客目录 [Alpha阶段]第十一次Scrum Meeting 基本信息 名称 时间 地点 时长 第六次Scrum Meeting 19/04/20 大运村寝室6楼 65mi ...