一、@ComponentScan注解
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package=“com.mengma”/>
</beans>
前面在Spring2.5中了解了<context:component-scan>将遍历扫描com.mengma路径下的所有类型定义,寻找标注了相应注解的类,并添加到IoC容器。<context:component-scan>扫描注解类型是@Component以及细化的@Contoller、@Service和@Repository,而且<context:component-scan>,同时会将AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor一并注册到容器中,所以,@Autowired和@Resource也能满足依赖注入。
- @ComponentScan("net.quickcodes.*")类似于配置文件中此行:<context:component-scan base-package=“com.mengma”/>
- @ComponentScan注解是什么?@ComponentScan主要就是定义扫描的路径,并从中找出标识了需要装配的类自动装配到spring的bean容器中;
- 做过web开发的同学一定都有用过@Controller,@Service,@Repository注解,查看其源码你会发现,他们中有一个共同的注解@Component,没错@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Autowired,@Resource,@Component注解的类到spring容器中;
- @ComponentScan注解的参数:
- value:扫描的路径;
- basePackages: 与value属性一样;
- basePackageClasses: 将指定数组中的多个class加入到spring容器中来;
- includeFilters:
- excludeFilters:
用法:
-
自动扫描路径下边带有@Controller,@Service,@Repository,@Component注解加入spring容器;
-
通过includeFilters加入扫描路径下没有以上注解的类加入spring容器;
-
通过excludeFilters过滤出不用加入spring容器的类;
-
自定义增加了@Component注解的注解方式;
二、@Configuration注解
- 从定义来看,
@Configuration
注解本质上还是@Component
,因此<context:component-scan/>
或者@ComponentScan
都能处理@Configuration
注解的类。 @Configuration
标记的类必须符合下面的要求:
- 配置类必须以类的形式提供(不能是工厂方法返回的实例),允许通过生成子类在运行时增强(cglib 动态代理);
- 配置类不能是
final
类(没法动态代理); - @Configuration不可以是匿名类;
- 配置注解通常为了通过
@Bean
注解生成 Spring 容器管理的类; - 配置类必须是非本地的(即不能在方法中声明,不能是 private);
- 任何嵌套配置类都必须声明为
static;
@Bean
方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有@Configuration
,也不会被特殊处理,只会作为普通的 bean);
3.@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的<beans>
,作用为:配置spring容器(应用上下文)
package com.dxz.demo.configuration;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TestConfiguration {
public TestConfiguration() {
System.out.println("TestConfiguration容器启动初始化。。。");
}
}
相当于:
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd" default-lazy-init="false">
</beans>
一般来讲,在配置类中,@Configuration和@Bean同时使用;
另外:
(1)在@configuration中引入扫描路径下的@ComponentScan
(2)在@configuration中引入spring的xml配置文件
(3)在@configuration中引入spring的properties配置文件
(4)在@configuration中引入其它注解配置
(5)@configuration嵌套(嵌套的Configuration必须是静态类)
通过配置类嵌套的配置类,达到组合多个配置类的目的。但注意内部类必须是静态类。
三、@Bean注解
以前使用XML配置的方式,bean是这样的:
<bean id="person" class="com.mengma.assembly.Person" />
而基于JavaConfig的配置形式是这样的:
@Configuration
public class Appconfig{
@Bean
public Person person(){
return new Person();
}
}
在xml中,bean与bean的依赖关系,这样配置:
<!--DAO配置-->
<bean id="userDAO" class="com.hisu.daoImpl.UserDAOImpl" scope="singleton">
...
</bean>
<!--service配置-->
<bean id="userService" class="com.hisu.serviceImpl.UserServiceImpl">
<property name="userDAO">
<ref bean="userDAO"/>
</property>
</bean>
现在,基于JavaConfig的配置形式是这样的:
@Configuration
public class Appconfig{
@Bean
public UserDAO userDAO(){
return new UserDAO();
}
@Bean
public UserService userService(){
return new UserService(userDAO());
}
}
说明:相信大多数人第一次看到上面 mockService()
中调用 dependencyService()
时,会认为这里的 DependencyService
和上面 @Bean
方法返回的 DependencyService
可能不是同一个对象,因此可能会通过下面的方式来替代这种方式:
@Autowired
private DependencyService dependencyService;
实际上不需要这么做,直接调用 dependencyService
() 方法返回的是同一个实例。
- 使用范围:@Bean是一个方法级别上的注解(返回某个实例的方法),等价于spring的xml配置文件中的
<bean>
,作用为:注册bean对象,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。 - @Bean不带参数:添加的bean的id为方法名,类型为方法返回值类型;
- @Bean(name=“testBean”)带上参数:添加的bean的id为testBean,类型为方法返回值类型;
- @Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为原型作用域;
- 如果一个bean的定义依赖其他bean,则直接调用对应的JavaConfig类中依赖bean的创建方法就可以了。
四、@Scope:@Bean的属性支持
@Scope 设置Spring容器如何新建Bean实例(方法上,得有@Bean)
其设置类型包括:
Singleton (单例,一个Spring容器中只有一个bean实例,默认模式),
Protetype (每次调用新建一个bean)