spring3.0使用annotation完全代替XML
@Service与@Component有什么不同?那天被问到这个问题,一时之间却想不起来,就利用这篇文章来纪录spring3.0中常用的annotation。
从spring2.5开始,annotation结合BeanPostProcessor成了扩展Spring
IoC容器的常用方法。Spring2.5增加了对JSR-250中@Resource, @PostConstruct,
@PreDestroy的支持,Spring 3.0又增加了对JSR-330 (Dependency Injection for Java)中
@Inject,@Qualifier, @Named, @Provider的支持。将相关的jsr
jar包丢到classpath,并注册相应的BeanPostProcessor,其它的一切spring会帮你完成。spring还提供了一个简便的方法,通过在context的XML配置文件中加入:
- <context:annotation-config/>
spring 会自动注册AutowiredAnnotationBeanPostProcessor,
CommonAnnotationBeanPostProcessor,
RequiredAnnotationBeanPostProcessor,代码中就可以使用@Autowired,
@Required等annotaion了。
再回到文章开头的问题吧。spring从2.5开始加入了classpath scanning的功能,来代替之前在xml中定义Bean。首先在context的XML配置文件中加入:
- <context:component-scan base-package="org.example"/>
spring
便会在org.example以及它的子package中查找所有的类,将符合条件的Bean注册在IoC容器当中。到3.0,spring引入了4种原型annotation(stereotype
annotaion),分别为@Component, @Serivce, @Controller,
@Repository。一般情况下只在将类加上@Componet,spring在扫描classpath的时候会自动检测到,并将这个类注册到IoC
容器中,在代码的其它部分,便可以借助@Autowired来注入这个Bean。后面的三种原型分别是特殊的@Conponet,适用于更加特殊的场合,比如Service层,Spring
MVC, DAO等。这一点从源码上也可以看出:
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Component
- public @interface Service {
- String value() default "";
- }
@Service本身就是被@Componet这个元注解(meta annotaion)标注的。因此对于这三个层的Bean,
spring的文档也推荐将它们标注为@Service,
@Controller与@Repository,因为这样更方便其它工具对这些特殊Bean的处理以及为它们加上相关AOP的
aspects,spring在后续版本的升级上也可能对它们增加更多的特殊语义。至于它们到底比普通的@Componet多了哪些
aspects,spring的文档上并没有详细说明,只简单地提到了对于@Repository,spring会自动加上exception
translation,用于转化持久层抛出的异常。我google了一下,包括spring论坛的帖子,也没能找到这方面的详细信息,这点希望熟悉spring源代码的朋友能够说说。
现在通过classpath
scanning以及@Component,@Autowired等annotation,我们已无须通过xml来定义Bean了。但还必须在application
context的xml中添加<context:annotation-config/>与<context:component-scan
base-package="org.example"/>。再进一步想,能不能把这个配置文件也去掉,实现真正的零配置?spring3.0原先Spring
JavaConfig项目的功能移到了Spring
Core里面,从而实现了利用Java代码来代替传统的XML配置文件,这个功能是通过@Configuration, @Bean, @Import,
@DependsOn等annotation实现的。
- @Configuration
- public class AppConfig {
- @Bean
- public GreetingDao greetingDao() {
- return new GreetingDao();
- }
- }
- public class GreetingDao {
- public String getGreeting(){
- return "Hi";
- }
- }
@configuration表明这个类包含Bean的定义,@Bean在这里就相当于原先的配置:<bean
id="greetingDao"
class="septem.demo.GreetingDao"/>。通过AnnotationConfigApplicationContext就可以使用这个Bean了:
- @Test
- public void test_java_config(){
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
- GreetingDao dao = ctx.getBean(GreetingDao.class);
- assertEquals("Hi", dao.getGreeting());
- }
注意AppConfig里面的greetingDao虽然是是直接new出来的,但它的默认scope仍是singleton,跟采用配置文件的情况是一样的,如果需要prototype,则可以另外为它加上@Scope("prototype")。上面采用的方法是手工将Bean定义在
@Configuration里面,我们同样可以让spring自动检测Bean,比如下面的GreetingSerivce:
- @Service
- public class GreetingService {
- public String sayHello(){
- return "Hello";
- }
- }
将GreetingService标注为@Service,就不需要在AppConfig里面注册了:
- @Test
- public void test_service(){
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
- ctx.scan("septem.demo");
- ctx.refresh();
- GreetingService service = ctx.getBean(GreetingService.class);
- assertEquals("Hello", service.sayHello());
- }
以上的ctx.scan("septem.demo")就相当于配置文件:<context:component-scan
base-package="septem.demo"/>。注意因为@Configuration本身也是被@Component这个meta-annotation标注的,所以AppConfig也不需要手工在
AnnotationConfigApplicationContext里注册,它同@Service一样会被自动检测到。Spring3.0还提供了
AnnotationConfigWebApplicationContext用来代替原先web项目中的
XmlWebApplicationContext,这样在web项目中同样可以实现真正的零配置了。Spring的官方文档还提供了针对更复杂情况的处理方法,有兴趣的朋友可以看看。
spring3.0使用annotation完全代替XML的更多相关文章
- spring3.0使用annotation完全代替XML(三)
很久之前写过两篇博客: spring3.0使用annotation完全代替XML spring3.0使用annotation完全代替XML(续) 用java config来代替XML,当时还遗留下一些 ...
- spring3.0使用annotation完全代替XML(续)
从回帖的反应来看,大多数人还是不赞成完全代替XML的,这点倒是在意料之中.我个人还是倾向于用代码来取代XML的Bean定义,当然这更多的是关乎个人偏好,不代表与我观点不同的人就是错的. 先来说说代码相 ...
- Spring3.0 入门进阶(三):基于XML方式的AOP使用
AOP是一个比较通用的概念,主要关注的内容用一句话来说就是"如何使用一个对象代理另外一个对象",不同的框架会有不同的实现,Aspectj 是在编译期就绑定了代理对象与被代理对象的关 ...
- Spring3.0 与 MyBatis框架 整合小实例
本文将在Eclipse开发环境下,采用Spring MVC + Spring + MyBatis + Maven + Log4J 框架搭建一个Java web 项目. 1. 环境准备: 1.1 创建数 ...
- 开发基础框架:mybatis-3.2.8 +hibernate4.0+spring3.0+struts2.3
一:项目下载地址(点击 Source code(zip)) https://github.com/fzxblgong/frame_2014-12-15/releases 版本:v1.2大小:20M 二 ...
- MyEclipse-10.0下Struts2.1+Spring3.0+Hibernate3.3整合过程
新建web project: 命名为SSH,做如下设置: 新建后的工程目录如下: 然后开始添加SSH框架,这里我按照struts-spring-hibernate顺序进行添加. 首先添加struts2 ...
- 模块化之Spring3.0 web fragment和gradle构建项目
1.背景 模块化开发很久以前就开始普及的概念.但是到了企业实际情况中,真正把模块化作为系统架构的核心的不多.或者说对模块化有这个意识,但是具体到底该如何实现,有些模糊,同时也许因为项目紧.任务中. ...
- Spring3.0之后->Spring MVC过滤器-HiddenHttpMethodFilter
浏览器form表单只支持GET与POST请求,而DELETE.PUT等method并不支持,spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET.POST.PUT ...
- spring3.0结合Redis在项目中的运用
推荐一个程序员的论坛网站:http://ourcoders.com/home/ 以下内容使用到的技术有:Redis缓存.SpringMVC.Maven.项目中使用了redis缓存,目的是在业务场景中, ...
随机推荐
- [MySQL]MySQL之权限管理
一.MySQL权限简介 关于mysql的权限简单的理解就是mysql允许你做你全力以内的事情,不可以越界.比如只允许你执行select操作,那么你就不能执行update操作.只允许你从某台机器上连接m ...
- DCIntrospect -iOS界面调试
原文:http://www.cnblogs.com/kw-ios/p/3523525.html 有时,设计稿上的UI很漂亮,布局也整齐,但自己用代码写出来的就不行,不是这里高一点,就是那是低一点,使用 ...
- js_继承
一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 复制代码代码如下: <SPAN style="<SPAN style="FONT- ...
- ABAP 常见查询问题解决方法
在ABAP 编程的时候会遇到查询单条语句的时候数能取对 但是条目数多了的话 会出现数不准确的问题 原因可能出现在查询使用了二分法查询方式 二分法查询下必须按排序的字段排序 还得按照排序的字段 ...
- SAP 出库单新版
*&---------------------------------------------------------------------* *& Report ZSDR045 ...
- iOS getter setter
getter setter 给成员变量起名字用的 setter方法 设置成员变量值 1. setter 方法一定是对象方法 不可能是类方法 2.一定没有返回值 3. 以set开头,并且set后面跟上需 ...
- 纯html页面之间传参
//页面引入//传参方法,可解析url参数 (function($){ $.getUrlParam = function(name) { var reg = new RegExp("(^|& ...
- sql server 锁
锁模式 锁模式 说明 共享 (S) 用于不更改或不更新数据的读取操作,如 SELECT 语句. 更新 (U) 用于可更新的资源中. 防止当多个会话在读取.锁定以及随后可能进行的资源更新时发生常见形式 ...
- Andriod学习笔记3:Mac 平台下搭建 CLion 集成开发环境
1. 安装Xcode 通过App store或者下载安装Xcode. 安装完成之后,最好启动一下Xcode,否则可能会报"Error:The C compiler "/usr/bi ...
- 关于 js 一些基本的东西
r.js 可以打包(可以实现前端文件的压缩与合并). 客户端尽量遵循 amd 规范. 推荐使用 requirejs 规范. requirejs 简单教程: http://www.runoob.com/ ...