`
septem
  • 浏览: 54445 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

spring3.0使用annotation完全代替XML

    博客分类:
  • java
阅读更多
@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的官方文档还提供了针对更复杂情况的处理方法,有兴趣的朋友可以看看。
分享到:
评论
28 楼 chrislee1982 2011-03-18  
配置声明式事物就不要使用Annotation方式了,超麻烦的
27 楼 kkfbai 2010-08-25  
Spring注解配置的确是很好的配置方式,但缺点也很明显,需要与源代码绑定。使用注解还是XML配置,看具体的情况。个人认为,对于经常变动的部分用XML好些,能与源码解耦,更加的灵活。对于固定的部分,采用注解的方式,减少对XML配置的管理
26 楼 zzy9zzy 2010-08-24  
使用annotation确实比xml写着方便,但是修改的话要改代码,改代码就要走测试流程,这是不太可以接受的。用annotation就是为了省事儿,但是反而增加了工作量,得不偿失。xml一般也是复制粘贴的用法多些,不需要很大工作量,甚至可以更偷懒的直接声明为自动装配——不过不推荐这么做,有问题的
25 楼 ronry 2010-08-22  
一看作者的标题就...怎么可能完全取代annotation呢.....
24 楼 水痕2000 2010-08-20  
约定大于配置
注解只能简单
一旦复杂的话
开发的人爽了
修改的人苦了
23 楼 Jazag.van 2010-08-20  
用注解就要整个的用上约定大于配置的思想
不然到时候维护起来会搞死人。
22 楼 liupesnap 2010-08-20  
用注解岂不是等同于硬编码了? 但有时候确实方便 尴尬。。。
21 楼 gylixyu 2010-08-20  
合理应用annotation,但是不能完全依赖
20 楼 caoyangx 2010-08-20  
用惯了注解方式,再用xml只有忆苦思甜的感觉。
19 楼 nakupanda 2010-08-20  
这和什么东西都写在代码里有何区别?
18 楼 huhuanqadn 2010-08-20  
我觉得这是一种倒退
17 楼 slaser 2010-08-20  
xml的可维护性明显更强, 只是开发效率差点。
16 楼 sam_chi 2010-08-19  
学习了,不过感觉XML还是不能扔的,我现在工作使用的是Spring2.5,平时像数据源、事务管理器之类的程序全局和框架性的东西使用XML来配置,自己写的DAO、Service等使用自动扫描,感觉不错
15 楼 qljcly 2010-08-19  
多谢楼主,关键是@Configuration这个,之前我一直用的2.5,换成3.0就有这个注解了
14 楼 septem 2010-08-19  
<div class="quote_title">IcedCoffee 写道</div>
<div class="quote_div">
<p>但是也会伴随着一些问题..比如OpenSessionView的那个拦截器我就不知道怎么在注解的情况下配置...</p>
</div>
<p>理论上讲XML里面的Bean都可以移到AppConfig里面,不过我之前用的都是OpenSessionInViewFilter,直接配置在web.xml里面,OpenSessionInViewInterceptor倒是没用过</p>
13 楼 septem 2010-08-19  
qljcly 写道

楼主,我问下,spring和hibernate结合时,hibernate实体类使用xml方式标注可以通过<prop key="hibernate.hbm2ddl.auto">create</prop>这种方式自动创建表结果,如果换成用注解的话可不可以实现相同功能?!!!?


也是能实现的,只要在AppConfig里面提供dataSource和sessionFactory
比如以下的XML配置
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="jdbc:hsqldb:mem:mymemdb"/>
		<property name="url" value="org.hsqldb.jdbcDriver"/>
		<property name="username" value="sa"/>
		<property name="password" value=""/>
	</bean>

	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<property name="packagesToScan">
		    <list>
		        <value>septem.model</value>
		    </list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
				<prop key="hibernate.hbm2ddl.auto">create</prop>
			</props>
		</property>
	</bean>


换成代码就是:
@Configuration
public class AppConfig {
    @Bean
    public GreetingDao greetingDao() {
        return new GreetingDao();
    }
    
    @Bean
    public ChildBean childBean(){
    	return new ChildBean();
    }
    
    @Bean(destroyMethod = "close")
    public BasicDataSource dataSource(){
    	BasicDataSource dataSource = new BasicDataSource();
    	dataSource.setUrl("jdbc:hsqldb:mem:mymemdb");
    	dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
    	dataSource.setUsername("sa");
    	dataSource.setPassword("");
    	return dataSource;
    }
    
    @Bean
    public AnnotationSessionFactoryBean sessionFactory(){
    	AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();
    	sessionFactory.setDataSource(dataSource());
    	sessionFactory.setPackagesToScan(new String[]{"septem.model"});
    	sessionFactory.setHibernateProperties(hibernateProperties());
    	return sessionFactory;
    }
    
    private Properties hibernateProperties(){
    	Properties p = new Properties();
    	p.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
    	p.setProperty("hibernate.hbm2ddl.auto", "create");
    	return p;
    }


当然你也可以将数据库的连接等信息保存在properties文件里面
12 楼 qljcly 2010-08-19  
septem 写道
@Service与@Component有什么不同?那天被问到这个问题,一时之间却想不起来,就利用这篇文章来纪录spring3.0中常用的annotation。


楼主,我问下,spring和hibernate结合时,hibernate实体类使用xml方式标注可以通过<prop key="hibernate.hbm2ddl.auto">create</prop>这种方式自动创建表结果,如果换成用注解的话可不可以实现相同功能?!!!?
11 楼 hxhnarkissos 2010-08-19  
zzy9zzy 写道
还是用xml配置文件好些。annotation配置出了问题还要去翻代码,不符合配置文件和代码分离的本意。


同此想法
如果想改xml中的参数 肯定要改代码 一想到改代码 会疯掉
10 楼 IcedCoffee 2010-08-19  
<p>现在的项目里用的就是spring3+jpa的注解,用起来很方便,只有事务我用的是xml配置。</p>
<p>dao层:</p>
<pre name="code" class="java">@Repository
public class UserDaoImpl extends BasicDaoImpl&lt;User, Serializable&gt;</pre>
<p> service层:</p>
<pre name="code" class="java">@Service
public class UserServiceImpl implements UserService {
@Inject
private Dao&lt;User, Serializable&gt; userDaoImpl;

public Dao&lt;User, Serializable&gt; getUserDaoImpl() {
return userDaoImpl;
}

public void setUserDaoImpl(Dao&lt;User, Serializable&gt; userDaoImpl) {
this.userDaoImpl = userDaoImpl;
}</pre>
<p> </p>
<p>但是也会伴随着一些问题..比如OpenSessionView的那个拦截器我就不知道怎么在注解的情况下配置...</p>
9 楼 obullxl 2010-08-19  
Spring的注解很强大,不过用XML我也觉得挺方便的。

相关推荐

    详解Spring_3.0基于Annotation的依赖注入实现

    ### 详解Spring 3.0基于Annotation的依赖注入实现 #### 概述 Spring框架作为一个广泛使用的Java开发框架,提供了强大的依赖注入(Dependency Injection, DI)能力,帮助开发者轻松管理和组织复杂的Java应用。随着...

    spring3.0jar包集合

    在Spring 3.0中,批注(Annotation)被更广泛地用于配置,替代了XML配置文件。例如,`@Autowired`用于自动装配依赖,`@Service`、`@Repository`和`@Controller`用于组件的标记,`@Transactional`用于标记事务边界。...

    权限管理 struts2 hiberante3.5 spring3.0 annotation

    Spring还支持基于XML的配置,但使用注解能减少配置文件的复杂性,提高代码的可读性。 在实际项目中,为了实现权限管理,你需要创建用户、角色和权限的实体类,并定义它们之间的关系。在数据库层面,这通常涉及到三...

    spring 3.0配置示例

    在本文中,我们将深入探讨Spring 3.0框架的配置示例,特别是关于文件上传和AJAX(异步JavaScript及XML)的注解使用。Spring框架是Java领域中广泛使用的轻量级应用框架,它提供了丰富的功能来简化企业级开发。在...

    spring 3.0 src

    3. **注解驱动的开发(Annotation-based Development)**:Spring 3.0大力推广注解,如@Service、@Repository、@Controller等,使得XML配置文件大大减少,提高了开发效率。 4. **JSR-303/JSR-349 Bean Validation**...

    Struts1.3 + Hibernate3.3 + Spring3.0 Annotation整合

    3. **配置Spring3.0**:在applicationContext.xml中声明Bean,包括Service层、DAO层的实例,以及Hibernate的相关配置。通过@Autowired注解实现依赖注入。 4. **整合Struts和Spring**:使用Spring的Struts插件,使...

    定时任务spring3.0

    Spring 3.0版本引入了对定时任务的支持,这是一个非常实用的功能,可以帮助开发者实现定期执行的任务,如数据同步、报表生成等。本文将深入探讨Spring 3.0中的定时任务实现,并结合Quartz库来进一步扩展定时任务的...

    spring 3.0 aop 实例

    4. **配置AOP**:在Spring 3.0中,可以使用XML配置或者注解方式来声明AOP。XML配置通过`&lt;aop:config&gt;`和`&lt;aop:advisor&gt;`等元素定义切入点和通知。注解方式则更加简洁,如`@Aspect`定义切面,`@Pointcut`定义切入点,...

    spring3.0两种事务管理配置

    这种方法只需要在 Spring 配置文件中定义一个事务管理对象(如 DataSourceTransactionManager),然后加入 `&lt;tx:annotation-driven/&gt;` 节点,引用该事务管理对象,然后即可在需要进行事务处理的类和方法使用 `@...

    spring3.0.jar

    2. **注解驱动开发(Annotation-based Development)**:在Spring 3.0中,注解成为主流的编程模式,如@Controller、@Service、@Repository和@Transactional等,减少了XML配置,提高了代码的可读性和可维护性。...

    spring3.0的xsd文件.rar

    总之,这个压缩包中的Spring 3.0 XSD文件是理解和使用Spring框架的关键资源。它们详细地定义了XML配置文件的语法,使得开发者可以更精确地控制Spring容器的行为,实现灵活的依赖注入、AOP、事务管理、数据库和消息...

    spring 3.0帮助文档

    2. **注解驱动开发(Annotation-based Development)**:Spring 3.0引入了大量的注解,如@Service、@Controller、@Repository和@Transactional,减少了XML配置,提高了代码可读性。例如,@Autowired用于自动装配依赖,...

    spring3.0 项目源码

    注解(Annotation)是Spring 3.0中的一个重要特性,它提供了一种元数据的方式,允许开发者在代码中嵌入信息,这些信息可以被编译器或运行时环境用来处理代码。Spring 3.0引入了如@Component、@Service、@Repository...

    Spring3.0源码2

    5. **REST支持**:Spring 3.0增加了对RESTful服务的支持,`org.springframework.web.bind.annotation.RequestMapping`和`@ResponseBody`注解用于处理HTTP请求并返回JSON或XML响应。 6. **JSR-303/JSR-349 Bean ...

    spring3.0 xsd文件

    Spring 3.0 XSD 文件是Spring框架在3.0版本中使用的XML Schema定义文件,它们主要用于配置Spring框架的应用上下文和服务。XSD文件的作用在于为XML配置提供结构化约束和验证,确保开发者遵循正确的格式编写配置。在...

    spring 3.0 jar包

    2. **注解驱动开发 (Annotation-based Development)**:Spring 3.0引入了大量的注解,如`@Component`、`@Service`、`@Repository`和`@Controller`,用于简化配置,使代码更加简洁。此外,`@Autowired`和`@Qualifier`...

    Spring3.0MVC注解(附实例)

    在Spring 3.0中,Spring MVC引入了强大的注解支持,使得开发Web应用程序变得更加简洁高效。本节将深入探讨Spring MVC注解及其在实际应用中的实现方式。 首先,Spring MVC注解允许开发者以声明式的方式配置控制器,...

    spring3.0 mvc 注解实现helloworld输出

    在本文中,我们将深入探讨如何使用Spring 3.0 MVC框架通过注解方式实现一个简单的“Hello, World!”输出。Spring MVC是Spring框架的一部分,它为构建基于模型-视图-控制器(MVC)架构的Web应用程序提供了一个强大的...

Global site tag (gtag.js) - Google Analytics