配置注解扫描
对于DI使用注解,将不再需要在Spring配置文件中声明部bean实例。Spring中使用注解,需要在原有Spring运行环境基础上在做一些改变,完成以下三个步骤:
(1)导入AOP的JAR包。因为注解的后台实现用到了AOP编程。- spring-aop-4.2.1.RELEASE.jar (2)需要更换配置文件头,即添加相应的约束:【context约束】
约束在%spring_home%\docs\spring-framework-reference\html\xsd-configuration.html文件中。
(3)需要在Spring配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。
1. 常见注解
1. @Component:定义Bean,需要在类上使用@Component,该注解的value属性用于指定该Bean的id值。
// 该注解参数省略了value属性,该属性用于指定Bena的id@Component("myStudent")public class Student{ private String name; private int age;}
另外:Spring还提供了3个功能基本和@Component等效的注解:
@Reposity:用于对DAO实现类进行注解【WEB层】 @Service:用于对Service实现类进行注解【业务层】 @Controller:用于对Controller实现类进行注解【持久层】 之所以创建这三个功能与@Component等效的注解,是为了以后对其进行功能上的扩展,是他们不再等效。2. @Scope:Bean的作用域,需要在类上使用注解@Scope,其value属性用于指定作用域,默认为singleton。
@Scope(scopeName="prototype")@Component("UserService")public class UserServiceImpl implements IUserService{ public void doSome(){ System.out.println("执行doSome()……"); }}
- @Value:基本类型属性输入。需要在属性上使用注解@Value,该注解的value属性用于指定要注入的值。使用该注解完成属性注入时,类中可无需setter。当然,若属性有setter,则也可将其加到setter上。 设置在属性上:通过反射的Field赋值,破坏了封装性。 设置在setter上:通过setter方法赋值,推荐使用。
@Component("myStudent")public class Student{ @Value("张三") private String name; @Value(23); private int age; @Override public String toString(){ return "Student [ name="+name+",age"+age+"]"; }}
3. @Autowired:自动装配,按类型byType注入域属性
需要在域属性上使用注解@Autowired,该注解默认使用按类型自动装配Bean的方式。使用该注解完成属性注入时,类中无需setter。当然,若属性有setter,则也可将其加到setter上。
@Autowired还有一个属性required,默认值为true。表示当匹配失败后,会终止程序运行,若将其值设置为false,则匹配失败后,将被忽略,未匹配的属性值为null。问题:如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象,从而引出了@Qualifier注解。
@Component("mySchool")public class School{ @Value("清华大学") private String name;}@Component("myStudent")public class Student{ @Value("张三") private String name; @Value(23) private int age; @Autowired private School school;}
4. @Qualifier:按名称注入域属性【前提:联合@Autowired一起使用】
需要在域属性上联合使用注解@Autowired与@Qualifier。@Qualifier的value属性用于指定要匹配的Bean的id值。同样类中无需setter,也可加到setter上。
@Autowired还有一个属性required,默认值为true。表示当匹配失败后,会终止程序运行,若将其值设置为false,则匹配失败后,将被忽略,未匹配的属性值为null。@Component("mySchool")public class School{ @Value("清华大学") private String name;}@Component("myStudent")public class Student{ @Value("张三") private String name; @Value(23) private int age; @Autowired(required=false) @Qualifier("mySchool") private School school;}
5. @Resource:自动装配【可按名称装配,也可按类型装配】
Spring提供了对JSR-250规范中定义@Resource标准注解的支持。@Resource注解即可以按名称匹配Bean,也可以按类型匹配Bean。使用该注解,要求JDK必须是6及以上版本。
@Resource相当于@Autowired和@Qualifier一起使用。 (1)按类型注入域属性 @Resource注解若不带任何参数,则会按照类型进行Bean的匹配注入。@Component("mySchool")public class School{ @Value("清华大学") private String name;}@Component("myStudent")public class Student{ @Value("张三") private String name; @Value(23) private int age; @Resource private School school;}
(2)按名称注入域属性
@Resource注解指定其name属性,则name的值即为按照名称进行匹配的Bean的id。@Component("mySchool")public class School{ @Value("清华大学") private String name;}@Component("myStudent")public class Student{ @Value("张三") private String name; @Value(23) private int age; @Resource(name="mySchool") private School school;}
6. @PostConstruct与@PreDestroy:Bean的声明始末
在方法上使用@PostConstruct,与原来的init-method等效。在方法上使用@PreDestroy,与destroy-method等效。
@PostConstructpublic void setUp(){ System.out.println("Bean初始化后,执行……");}@PreDestroypublic void tearDown(){ System.out.println("Bean销毁前,执行……");}
7. 使用JavaConfing进行配置(了解)
JavaConfig是在Spring3.0开始从一个独立的项目并入到Spring中的。JavaConfig可以堪称一个用于完成Bean装配的Spring配置文件,即Spring容器,只不过该容器不是XML文件,而是由程序员使用Java自己编写的Java类。
(1)定义实体类public class School{ private String name; // setter // toString()}public class Student{ private String name; private int age; private School school; // setter // toString()}
(2)@Configuration/@Bean:定义JavaConfig类
对于一个POJO类,在类上使用@Configuration注解,将会使当前类作为一个Spring的容器来使用,用于完成bean的创建。 在该JavaConfig的方法上使用@Bean,将会使一个普通方法所返回的结果变为指定名称的Bean实例。 当然,在JavaConfig中,也可以完成域属性的自动注入。 A: byType方式的域属性自动注入// 该注解表示:本类为JavaConfig@Configurationpublic class MyJavaConfig{ // 该注解表示:方法返回的对象Bean的名称(id)为mySchool @Bean(name="mySchool") public School initialSchool(){ return new School("清华大学"); } // 采用byType自动注入school属性。当然,要求当前JavaConfig // 类中只能与一个方法返回值与Student的School属性具有is-a关系 @Bean(name="myStudent",autowire=Autowire.BY_TYPE) public Student initialStudent(){ return new Student("张三",23); }}
B: byName方式的域属性自动注入
// 该注解表示:本类为JavaConfig@Configurationpublic class MyJavaConfig{ // 由于Student的School属性采用byName方式,并要将这里定义的对象赋值给School属性,所以要求这里的name属性值要与School属性值相同。 @Bean(name="mySchool") public School initialSchool(){ return new School("清华大学"); } // 采用byName自动注入school属性。要求School名要与JavaConfig中定义某Bean的name属性值相同。 @Bean(name="myStudent",autowire=Autowire.BY_NAME) public Student initialStudent(){ return new Student("张三",23); }}