个人感觉适合在小团队开发或模块分工极其明确的合作中使用,无需再花时间去编写重复的xml文件。但注解隐藏了各种依赖注入关系和bean实现,不像配置文件那样一目了然,在多人项目及阅读源码时并不方便。
环境:与第一章相同。依赖于之前创建的工程、库、接口定义。
1.注解实现接口
TestServiceAnnoImpl注解实现service接口。
package com.sunbin.test.testSpring.service.impl; import com.sunbin.test.testSpring.dao.TestDao; import com.sunbin.test.testSpring.service.TestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TestServiceAnnoImpl implements TestService { @Autowired private TestDao testDao; public String test(String string) { // TODO Auto-generated method stub return "testServiceAnnoImpl.test:"+testDao.test(string); } }
TestDaoAnnoImpl注解实现dao接口。
package com.sunbin.test.testSpring.dao.impl; import com.sunbin.test.testSpring.dao.TestDao; import org.springframework.stereotype.Repository; @Repository public class TestDaoAnnoImpl implements TestDao { @Override public String test(String string) { // TODO Auto-generated method stub return "testDaoAnnoImpl.test:"+string; } }
@Repository注解只能用在dao层,该注解不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。
@Service 通常作用在业务层,但是目前该功能与 @Component 相同。
@Constroller 通常作用在控制层,但是目前该功能与 @Component 相同。
@Component 是一个泛化的概念,仅仅表示一个组件 (Bean),可以作用在任何层次。
具体区别见 http://blog.csdn.net/ye1992/article/details/19971467
@Autowired将自动按照类型注入bean。
与此类似的注解还有:
@Inject是jsr330中的规范,通过AutowiredAnnotationBeanPostProcessor类实现的依赖注入。
@Resource是jsr250规范的实现,通过CommonAnnotationBeanPostProcessor类实现依赖注入。
具体区别见 http://blog.csdn.net/u012734441/article/details/51706504
2.测试
创建测试类TestAnno。
package com.sunbin.test.testSpring.main; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.sunbin.test.testSpring.service.TestService; public class TestAnno { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.sunbin.test.testSpring"); TestService testService =(TestService) applicationContext.getBean(TestService.class); System.out.println(testService.test("helloWorldAnno")); } }
测试类中扫描com.sunbin.test.testSpring包下的所有注解,创建ApplicationContext、创建Bean、自动注入。
运行结果如下:
- testServiceAnnoImpl.test:testDaoAnnoImpl.test:helloWorldAnno
说明Test、Service、Dao各层扫描注解、创建、注入、调用成功。
3.xml配置扫描注解
如果Context创建的入口必须有xml配置文件(如web项目),就不方便用AnnotationConfigApplicationContext来加载spring。可以通过在xml中增加配置来自动扫描指定包。
新增spring配置文件root-annonation.xml:
<?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" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName" default-lazy-init="true"> <context:annotation-config /> <context:component-scan base-package="com.sunbin"></context:component-scan> </beans>
测试类修改如下:
package com.sunbin.test.testSpring.main; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.sunbin.test.testSpring.service.TestService; public class TestAnno { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] { "root-annonation.xml" }); TestService testService =(TestService) applicationContext.getBean(TestService.class); System.out.println(testService.test("helloWorldAnno")); } }
运行结果相同。
注意xml配置中自动注入方式是byName(也可以改为byType),注解默认是byType。如果该接口类型的实现Bean有多个,spring装载时会报错。