Spring3.X学习笔记3-基于注解和基于Java类的配置
来源:互联网 发布:windows是那个公司 编辑:程序博客网 时间:2024/06/05 09:04
上一篇文章里我们主要介绍了基于XML Schemal的配置方式。本篇文章里将介绍另外两种提供Bean定义的方式,基于注解和基于Java类的配置。
1、基于注解的配置
不管是XML还是注解,他们都是表达Bean定义的载体,其实质都是为Spring容器提供Bean定义的信息,表现形式上是将XML定义的东西通过类注解进行描述。Spring从2.0开始引入基于注解的配置方式,在3.0时得到进一步的完善。
下面是使用注解定义一个DAO的Bean:
package com.hhxs.bbt.dao;import org.springframework.stereotype.Component;// 1.通过Repository定义一个DAO的Bean@Component("userDao")public class UserDao { ...}
在上面1
处,使用@Component注解在UserDao类声明处对类进行标注,它可以被Spring容器识别,Spring容器自动将POJO转换为容器管理的Bean。它和以下的XML配置是等效的:
<Bean id="userDao" class="com.hhxs.bbt.dao.UserDao">
除了@Component以外,Spring提供了三个功能基本和@Component等效的注解,它们分别用于对DAO、Service及Web层的Controller进行注解,所以也称这些注解为Bean的衍型注解:
- @Repository:用于对DAO实现类进行标注;
- @Service:用于对Service实现类进行标注;
- @Controller:用于对Controller实现类进行标注。
在@Component之外提供这三个注解,是为了让注解类本身的用途更加清晰,此外Spring还赋予了它们一些特殊功能。
1.1 使用注解配置信息启动Spring容器
Spring在2.5 后提供了一个context的命名空间,它提供了通过扫描类包以应用注解定义Bean的方式:
<?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.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd> <description>Spring公共配置 </description> <!-- 1.扫描类包以应用注解定义的Bean --> <context:component-scan base-package="com.hhxs.bbt" /></beans>
在上面1
处通过context
命名空间的compnent-scan的base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里的所有类,并从类的注解信息中获取Bean的定义信息。
如果仅希望扫描特定的类而非基包下的所有类,那么可以使用resource-pattern属性过滤特定的类,如下所示:
<context:component-scan base-package="com.hhxs.bbt" resource-pattern="dao/*.class"/>
默认情况下resource-pattern属性的值为**/*.class
,即基包里的所有类。这里我们设置为dao/*.class
,则Spring仅会扫描基包里dao子包中的类。通过resource-pattern属性仅可按资源名称对基包中的类进行过滤,如果需要更详细的过滤,则需要用到<contex:component-scan>
的过滤子元素:
<context:component-scan base-package="com.hhxs.bbt"> <context:include-filter type="regex" expression="com.\hhxs.\bbt.*"/> <context:exclude-filter type="aspectj" expression="com.hhxs.bbt..*Controller+"/></context>
<context:include-filter>
表示要包含的目标类<context:exclude-filter>
表示要排除在外的目标类
一个<context:component-scan>
下可以包含若干个<context:include-filter>
和<context:exclude-filter>
元素。这两个过滤元素均支持多种类型的过滤表达式,如下表所示:
1.2 自动装配Bean
spring使用@Autowired注解实现Bean的依赖注入。@Autowired默认按类型匹配的方式,在容器查找匹配Bean,
**当且仅有一个匹配的**Bean时,Spring将其注入到@Autowired标注的变量中。
package com.hhxs.bbt.service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class LogonService { @Autowired private LogDao logDao; @Autowired private UserDao userDao; ...}
如果容器中没有一个和标注变量类型匹配的bean,Spring容器启动时将报NoSuchBeanDefinitionException
异常。如果希望不抛出异常可以使用@Autowired(required=false)进行标注。默认情况下,@Autowired的required属性值为true。
如果容器中有一个以上匹配的Bean时,可以通过@Qualifier注解限定Bean的名称。
package com.hhxs.bbt.service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;@Servicepublic class LogonService { @Autowired private LogDao logDao; @Autowired @Qualifier("userDao") private UserDao userDao; ...}
对集合类进行标注
如果对类中集合类的变量和方法入参进行@Autowired标注,Spring会将容器中类型匹配的所有Bean都自动注入进来。这是一个很好的特性,所以在这里介绍下。
package com.hhxs.bbt.service;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;@Servicepublic class MyComponent { // Spring会将容器中所有类型为Plugin的Bean注入到这个变量中 @Autowired(required=false) private List<Plugin> plugins; public List<Plugin> getPlugins() { return plugins; }}
Spring如果发现变量是一个集合类,则它会将容器中匹配集合元素类型的所有Bean都注入进来。这里,Plugin为一个接口,它拥有两个实现类,分别是OnePlugin和TwoPlugin,这两个实现类都通过@Component标注为Bean,则Spring会将这两个Bean都注入到plugins中。
2、基于Java类的配置
2.1 使用Java类提供Bean定义信息
JavaConfig是Spring的一个子项目,它旨在通过Java类的方式提供Bean的定义信息。Spring3.0基于Java类配置的核心即取材于JavaConfig。
普通的POJO只要标注@Configuration注解,就可以为Spring容器提供Bean定义的信息了,每个标注了@Bean的类方法都相当于提供一个Bean的定义信息。
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;// 1.将一个POJO标注定义为Bean的配置类@Configurationpublic class AppConf { // 2.以下两个方法定义了两个Bean,并提供了Bean的实例化逻辑 @Bean public UserDao userDao() { return new UserDao(); } @Bean public LogDao logDao() { return new LogDao() } @Bean public LogonService logonService() { LogonServcie logonService = new LogonService(); // 将上面2处定义的Bean注入到logonService的Bean logonService.setLogDao(logDao()); logonService.setUserDao(userDao()); return logonService; }}
1
处在AppConf类的定义处标注了@Configuration注解,说明这个类可用于为Spring提供Bean信息。类的方法出可以标注@Bean注解,Bean的类型由方法返回值类型决定,名称默认和方法名相同,也可通过@Bean(name=”userDao”)显示指定Bean的名称。
上面的配置和以下XML配置等效:
<bean id="userDao" class="com.hhxs.bbt.dao.UserDao" /><bean id="logDao" class="com.hhxs.bbt.dao.LogDao" /><bean id="userDao" class="com.hhxs.bbt.conf.LogonService" p:logDao-ref="userDao" p:userDao-ref="logDao" />
2.2 使用基于Java类的配置信息启动Spring容器
2.2.1 直接通过@Configuration类启动Spring容器
Spring提供了一个AnnotationConfigApplicationContext类,它能够直接通过标注@Configuration的Java类启动Spring容器。以下两种方式是等效的:
第一种:
package com.hhxs.bbt.conf;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class JavaConfigTest { public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class); LogonService logonService = ctx.getBean(logonService.class); logonService.printHello(); }}
第二种:
package com.hhxs.bbt.conf;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class JavaConfigTest { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); // 注册多个@Configuration配置类 ctx.register(DaoConfig.Class); ctx.register(ServiceConfig.class); // 刷新容器以应用这些注册的配置类 ctx.refresh(); LogonService logonService = ctx.getBean(logonService.class); logonService.printHello(); }}
可以通过代码一个一个注册配置类,也可以通过@Import将多个配置类组装到一个配置类中,这样仅需要注册这个组装好的配置类就可以启动容器了。
package com.hhxs.bbt.conf;import org.springframework.beans.factory.annotation.Configurable;import org.springframework.context.annotation.Import;@Configurable@Import(DaoConfig.class)public class ServiceConfig { @Bean public LogonService logonService() { LogonService logonService = new LogonService(); return logonService; }}
我们既可以在XML配置文件中引用@Configuration的配置,也可以通过Configuration配置类中引用XML配置信息。只要不同形式的Bean定义信息能够加载到Spring容器中,Spring就能足够“智能”的完成Bean之间的装配。
3、不同配置方式比较
配置方式比较:
<bean class="com.hhxs.bbt.UserDao">
Bean实现类出通过标注 @Component、@Repository、@Service、@Controller 在标注了@Configuration的Java类中,通过在类方法上标注@Bean定义一个Bean。方法必须提供Bean的实例化逻辑。 Bean名称 通过的id或name属性定义 通过注解的value属性定义,如@Component(“userDao”)。默认名称为小写字母打头的类名(不带包名):userDao 通过@Bean的name属性定义,如@Bean(“userDao”),默认名称为方法名。 Bean注入 通过子元素或通过p命名空间的动态属性 通过在成员变量或方法入参出标注@Autowired,按类型匹配自动注入 可以通过在方法处通过@Autowired使方法入参绑定Bean,然后在方法中通过代码进行注入,还可以通过调用配置类的@Bean方法进行注入 Bean生命过程方法 通过的init-method和destory-method属性指定Bean实现类的方法名。最多只能指定一个初始化方法和一个销毁方法 通过在目标方法上标注@PostConstruct和@PreDestroy注解指定初始化或销毁方法,可以定义任意多个方法 通过@Bean的initmethod或destoryMethod指定一个初始化或销毁方法。 Bean作用范围 通过的scope属性指定 通过在类定义出标注@Scope指定 通过在Bean方法定义处标注@Scope指定 Bean延迟初始化 通过的lazy-init属性指定,默认为default,继承与的default-lazy-init设置,该值默认为false 通过在类定义处标注@Lazy指定,如@Lazy(true) 通过在Bean方法定义处标注@Lazy指定
使用场景建议:
2)命名空间的配置 Bean实现类是当前项目开发的,
可以直接在Java类中使用基于注解的配置 基于Java类配置的优势在于
可以通过代码方式控制Bean初
始化的整体逻辑。
- Spring3.X学习笔记3-基于注解和基于Java类的配置
- 基于注解的spring3.0.x MVC学习笔记(二)
- 基于注解的spring3.0.x MVC学习笔记(一)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(八)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(二)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(三)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(四)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(五)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(六)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(七)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(八)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(九)
- 基于spring source tools suite注解的spring3.0.x MVC学习笔记(一)
- 基于spring source tools suite注解的spring3.0.x MVC学习笔记(二)
- Struts2+Spring3 基于注解的配置
- spring3-基于注解的AOP
- 基于注解的spring 3.0.x MVC学习笔记(一)
- 基于annotation注解的Spring3 MVC之一 HelloWorld 例子学习笔记
- js根据ip地址获取用户地点的接口使用方法
- 8年经验的IT人分享受用一生的IT职业发展规划
- 分别求1+2+3+...+10,20+21+22+...+30与35+36+37+...+45的和
- Intellij idea部署web项目
- 运算符,分支结构.
- Spring3.X学习笔记3-基于注解和基于Java类的配置
- 深入理解java多态性
- Myececlipse安装svn插件的两种方法
- 每天一道LeetCode-----找到给定序列中所有和为某个值的集合或集合个数,序列中可以有/无重复项,集合元素顺序不同算不同集合等
- 数据库自动化运维平台--DDL平台服务
- lvm定义&创建&删除&拉伸&缩减
- 全文检索引擎Solr系列—–全文检索基本原理
- rtmp complex handshake,变更的握手,支持h264/aac
- 常见排序算法