Spring中三种配置Bean的方式

时间:2022-12-29 17:41:27

Spring中三种配置Bean的方式分别是:

  1. 基于XML的配置方式
  2. 基于注解的配置方式
  3. 基于Java类的配置方式

一.基于XML的配置

这个很简单,所以如何使用就略掉。

二.基于注解的配置

Spring2.0开始引入基于注解的配置方式,即Bean的定义信息可以通过在Bean的实现类上标注注解实现。
不清楚Java注解的参阅Java注解基本原理

@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,
过滤表达式所支持的类型如下表所示:

Spring中三种配置Bean的方式

在这些类型当中,除了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";
}
}

然后还需要一个测试类,来查看配置是否成功

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中三种配置Bean的方式的更多相关文章

  1. (转)Spring的三种实例化Bean的方式

    http://blog.csdn.net/yerenyuan_pku/article/details/52832793 Spring提供了三种实例化Bean的方式. 使用类构造器实例化. <be ...

  2. Spring中四种实例化bean的方式

    本文主要介绍四种实例化bean的方式(注入方式) 或者叫依赖对象实例化的四种方式.上面的程序,创建bean 对象,用的是什么方法 ,用的是构造函数的方式 (Spring 可以在构造函数私有化的情况下把 ...

  3. Spring第四弹—–Spring的三种实例化bean的方式

    1.使用类构造器实例化   1 <bean id=“orderService" class="cn.itcast.OrderServiceBean"/> 2. ...

  4. 【转】ZYNQ中三种实现GPIO的方式

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/husipeng86/article/det ...

  5. 【转】Spring 中三种Bean配置方式比较

    今天被问到Spring中Bean的配置方式,很尴尬,只想到了基于XML的配置方式,其他的一时想不起来了,看来Spring的内容还没有完全梳理清楚,见到一篇不错的文章,就先转过来了. 以前Java框架基 ...

  6. Spring 中三种Bean配置方式比较

    今天被问到Spring中Bean的配置方式,很尴尬,只想到了基于XML的配置方式,其他的一时想不起来了,看来Spring的内容还没有完全梳理清楚,见到一篇不错的文章,就先转过来了. 以前Java框架基 ...

  7. Spring —— 三种配置数据源的方式:spring内置、c3p0、dbcp

    01.Spring内置数据源配置Class:DriverManagerDataSource全限定名:org.springframework.jdbc.datasource.DriverManagerD ...

  8. spring三种实例化bean的方式

    1构造函数实例化 2静态工厂方法实例化 3实例工厂方法实例化 service接口: package service; public interface PersonService { public v ...

  9. 三种实例化bean的方式

    在spring中有三中实例化bean的方式: 一.使用构造器实例化:(90%通常使用的一个方法) 二.使用静态工厂方法实例化: 三.使用实例化工厂方法实例化. 每种实例化所采用的配置是不一样的: 一. ...

随机推荐

  1. IE的F12开发人员工具不显示问题

    按下F12之后,开发人员工具在桌面上看不到,但是任务栏里有显示.将鼠标放在任务栏的开发人员工具上,出现一片透明的区域,选中之后却出不来.将鼠标移动到开发人员工具的缩略图上,右键-最大化,工具就全屏出现 ...

  2. 【代码笔记】iOS-将log日志保存到文件

    代码: #import "AppDelegate.h" #import "RootViewController.h" @implementation AppDe ...

  3. &period;Net的要知道的一些事

    1.什么是.NET?什么是CLI?什么是CLR?IL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式? .Net是微软推出的框架 CLI是公共语言接口(规范) CLR是公共语言 ...

  4. app上传到app Store常见问题

    一.首先看一下提交界面出现的问题(能成功打包成.ipa) 产生问题的原因如下:由于工程中含有sub project,而sub project中有private或public的文件导致的.这样的应用往往 ...

  5. ubuntu安装svn manager

    环境:系统ubuntu14.04 0. 更新软件库 sudo apt-get update sudo apt-get upgrade -y 1. 安装apache,svn,svn的apache模块 s ...

  6. JavaScript Garden

    Objects Object Usage and Properties Everything in JavaScript acts like an object, with the only two ...

  7. java实现电脑远程控制完整源代码(转)

    Java JDK1.4 的Robot对象,该对象可以完成屏幕图像截取操作,控制鼠标,键盘,如此便可以轻而易举地实现远程服务器的控制.本文向大家介绍如何用Java Robot对象实现远程服务器的控制,并 ...

  8. Is ICARSCAN same or old version of LAUNCH X431 Easydiag &quest;

    LAUNCH X431 Easydiag 2.0 is basically the same OBD-II Bluetooth device – but the software supplied w ...

  9. 2019&sol;4&sol;8 wen text

    构造器产生对象的步骤:1.为对象在内存中申请内存空间. 2.对对象的属性申请内存空间. 3.为属性进行初始化. 4.执行构造器中编写的其他代码. 静态方法调用:    类名.方法 非静态方法调用:  ...

  10. 使用requests库提交multipart&sol;form-data 格式的请求

    前言: Requests是用Python语言编写,基于urllib,采用Apache2 Licensed开源协议的HTTP库.它比urllib更加方便,可以节约我们大量的工作,完全满足HTTP测试需求 ...