spring注解@ComponentScan、@Configuration、@Bean、@Scope
java配置类相关注解:@ComponentScan、@Configuration、@Bean
一、@ComponentScan注解
- @ComponentScan("net.quickcodes.*")类似于配置文件中的一行:
- @ComponentScan注解是什么?@ComponentScan主要就是定义扫描的路径,并从中找出标识了需要装配的类自动装配到spring的bean容器中;
- 做过web开发的同学一定都有用过@Controller,@Service,@Repository注解,查看其源码你会发现,他们中有一个共同的注解@Component,没错@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@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
标记的类必须符合下面的要求:
(1)、配置类必须以类的形式提供(不能是工厂方法返回的实例),允许通过生成子类在运行时增强(cglib 动态代理);
(2)、配置类不能是 final
类(没法动态代理)。
(3)、@Configuration不可以是匿名类;
(4)、配置注解通常为了通过 @Bean
注解生成 Spring 容器管理的类;
(5)、配置类必须是非本地的(即不能在方法中声明,不能是 private);
(6)、任何嵌套配置类都必须声明为static;
(7)、@Bean
方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有 @Configuration
,也不会被特殊处理,只会作为普通的 bean);
[email protected]标注在类上,相当于把该类作为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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd" default-lazy-init="false">
</beans>
一般来讲,在配置类中,@Configuration和@Bean同时使用;
另外:(1)在@configuration中引入spring的xml配置文件
(2)在@configuration中引入其它注解配置
(3)@configuration嵌套(嵌套的Configuration必须是静态类)
通过配置类嵌套的配置类,达到组合多个配置类的目的。但注意内部类必须是静态类。
三、@Bean注解
以前使用XML配置的方式,bean是这样的:
而基于JavaConfig的配置形式是这样的:
在xml中,bean与bean的依赖关系,这样配置:
现在,基于JavaConfig的配置形式是这样的:
说明:相信大多数人第一次看到上面 mockService()
中调用 dependencyService()
时,会认为这里的 DependencyService
和上面 @Bean
方法返回的 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的创建方法就可以了。
@Autowired
private DependencyService dependencyService;
实际上不需要这么做,直接调用 dependencyService
() 方法返回的是同一个实例。
但是,如果将@configuration注解,换成@component注解, 那么这两个就不是同一个实例了。
- @Bean下管理bean的生命周期
(1)可以使用基于 Java 的配置来管理 bean 的生命周期。@Bean
支持两种属性,即 initMethod
和destroyMethod
,这些属性可用于定义生命周期方法。在实例化 bean 或即将销毁它时,容器便可调用生命周期方法。生命周期方法也称为回调方法,因为它将由容器调用。使用 @Bean
注释注册的 bean 也支持 JSR-250 规定的标准 @PostConstruct
和 @PreDestroy
注释。
四、@Scope:@Bean的属性支持
@Scope 设置Spring容器如何新建Bean实例(方法上,得有@Bean)
其设置类型包括:
Singleton (单例,一个Spring容器中只有一个bean实例,默认模式),
Protetype (每次调用新建一个bean)