精华帖 (0) :: 良好帖 (13) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-08-18
最后修改:2010-08-18
从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的官方文档还提供了针对更复杂情况的处理方法,有兴趣的朋友可以看看。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-08-18
完全的用注解代替配置文档太过于绝对,至少对于我来说是.
最近在学习注解 感觉确实比配置方便很多 但是有些东西还是配置文档好点 看起一目了然 |
|
返回顶楼 | |
发表时间:2010-08-18
我还是觉得该用annotation用annotation,该用xml用xml。
|
|
返回顶楼 | |
发表时间:2010-08-18
感觉hibernate用annotation还行,
spring里面用annotation修改不方便,只有事务管理用annotation |
|
返回顶楼 | |
发表时间:2010-08-19
还是用xml配置文件好些。annotation配置出了问题还要去翻代码,不符合配置文件和代码分离的本意。
|
|
返回顶楼 | |
发表时间:2010-08-19
fly2never 写道 感觉hibernate用annotation还行,
spring里面用annotation修改不方便,只有事务管理用annotation 事务管理适合用xml吧,我习惯事务在xml中集中配置 |
|
返回顶楼 | |
发表时间:2010-08-19
<bean parent="">
parent用啥annotation? |
|
返回顶楼 | |
发表时间:2010-08-19
qinglangee 写道 fly2never 写道 感觉hibernate用annotation还行,
spring里面用annotation修改不方便,只有事务管理用annotation 事务管理适合用xml吧,我习惯事务在xml中集中配置 集中管理的用xml,特别的用annotation,这样也挺好。 hibernate用annotation,确实要比xml好。 |
|
返回顶楼 | |
发表时间:2010-08-19
frogfool 写道 <bean parent="">
parent用啥annotation? 应该可以通过以下的方式实现吧 public abstract class ParentBean { @Value("parent") String name; } public class ChildBean extends ParentBean{ @Value("child") String name; } @Configuration public class AppConfig { @Bean public GreetingDao greetingDao() { return new GreetingDao(); } @Bean public ChildBean childBean(){ return new ChildBean(); } } @Test public void test_parent_bean(){ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.scan("septem.demo"); ctx.refresh(); ChildBean child = ctx.getBean(ChildBean.class); assertEquals("child", child.name); } |
|
返回顶楼 | |
发表时间:2010-08-19
Spring的注解很强大,不过用XML我也觉得挺方便的。
|
|
返回顶楼 | |