@Conditional
条件装配Bean
- 实现org.springframework.context.annotation.Condition接口
public class CustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// true 进行装配,false不进行装配
return false;
}
}
- Bean上配置@Conditional(Condition.class)
@Configuration
public class CustomConfig {
@Conditional(CustomCondition.class)
@Bean
public Person person() {
return new Person();
}
}
当matches方法返回true的时候进行注册当前@Bean,否则不注册。该注解也可以放到配置类上,matches方法返回true的时候进行注册当前配置类,否侧不注册。
@Profile
环境注解,底层使用的是@Conditional
@Import
快捷注册Bean,默认名称为类的全路径
- 直接导入类
@Configuration
@Import(Person.class)
public class CustomConfig {
}
- 导入实现org.springframework.context.annotation.ImportSelector类
public class CustomImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{Person.class.getName()};
}
}
@Configuration
@Import(CustomImportSelector.class)
public class CustomConfig {
}
- 导入实现org.springframework.context.annotation.ImportBeanDefinitionRegistrar类
public class CustomImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
// 自行注册BeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(Person.class);
registry.registerBeanDefinition(“person”,beanDefinition);
}
}
@Configuration
@Import(CustomImportBeanDefinitionRegistrar.class)
public class CustomConfig {
}
@ImportResource
导入资源xml文件
资源文件名称spring/application-spring.xml
@Configuration
@ImportResource(“classpath:/spring/application-spring.xml”)
public class CustomConfig {
}
常见问题
@Configuration、其他注解与@Bean结合使用有什么不同
答:@Configuration注解使用的其实也是一个Bean,但本身是BeanFatory,是经过CGLIB进行增强的Bean,其他注解(@Component、@Service、@Controller、@Repository)使用的就是一个简单的Bean
常用注解
@Autowired
Spring自带的自动注入,注解的属性required来支持是否必须要进行依赖注入。根据以下规则进行查找进行注入
1、 根据类型查找,只查询一个直接返回
2、 根据名称查找
@Service
public class PersonService {
@Autowired
private PersonMapper personMapper;
}
可以结合以下注解进行使用
- @Qualifier
指定名称进行依赖注入
@Service
public class PersonService {
@Autowired
@Qualifier(“personMapper”)
private PersonMapper personMapper;
}
- @Primary
指定优先进行依赖注入
@Service
public class PersonService {
@Autowired
private PersonMapper personMapper;
}
@Configuration
@ComponentScan({“top.felixfly.spring.annotation.mapper”,“top.felixfly.spring.annotation.service”})
public class CustomConfig {
// 优先注入
@Bean(“personMapper2”)
@Primary
public PersonMapper personMapper(){
return new PersonMapper();
}
}
只有一个有参构造器时,@Autowired可以省略,可以自动进行注入
@Resource
Java规范(JSR250)的注解,默认按照属性的名称进行依赖查找匹配,也可以用属性name进行强制指定,但不支持与@Primary注解结合使用和required是否必须要进行依赖注入
@Service
public class PersonService {
@Resource
private PersonMapper personMapper;
}
@Service
public class PersonService {
// 强制指定Bean
@Resource(name=“personMapper2”)
private PersonMapper personMapper;
}
@Inject
Java规范的注解(JSR330),功能与@Autowired一样,但不支持required是否必须要进行依赖注入。需要引入javax.inject
javax.inject
javax.inject
1
@Service
public class PersonService {
@Inject
private PersonMapper personMapper;
}
构造器注入
@Configuration
public class AppConfig {
@Bean
public BeanOne beanOne() {
// 构造器注入
return new BeanOne(beanTwo());
}
@Bean
public BeanOne beanThree(BeanTwo beanTwo) {
// 构造器注入
return new BeanOne(beanTwo);
}
@Bean
public BeanTwo beanTwo() {
return new BeanTwo();
}
}
Setter方法注入
public class BeanTwo {
@Autowired
public void setBeanOne(BeanOne beanOne) {
this.beanOne = beanOne;
}
}
Aware接口
自定义组件注入Spring底层的组件,比如ApplicationContext,这些Awa
【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
re接口一般通过Processor进行处理。ApplicationContextAwareProcessor处理EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware
| ApplicationContextAware | ApplicationContext |
| — | — |
| ApplicationEventPublisherAware | ApplicationContext事件发布器 |
| BeanClassLoaderAware | 类加载器 |
| BeanFactoryAware | Bean 工厂 |
| BeanNameAware | Bean 名称 |
| BootstrapContextAware | BootstrapContext |
| MessageSourceAware | 国际化管理 |
| NotificationPublisherAware Spring | JMX通知发布器 |
| ResourceLoaderAware | 资源加载器 |
| EmbeddedValueResolverAware | @Value解析器 |
| EnvironmentAware | 环境变量 |
循环依赖的问题
答:循环依赖的产生,BeanA依赖BeanB,BeanB依赖BeanC,而BeanC又依赖于BeanA,这时候就会产生循环依赖的问题,单例Bean中通过构造器注入会产生循环依赖的问题,会产生BeanCurrentlyInCreationException,通过Setter方法注入不会产生异常,可以解决循环依赖问题。原型@Bean通过Setter方法注入依然会产生BeanCurrentlyInCreationException,没办法解决循环依赖问题。
Bean的生命周期包含实例化–>初始化–>销毁,单实例Bean实例化在容器创建的时候进行实例化以及初始化,销毁在容器关闭的时候进行调用;多实例Bean在获取Bean的时候进行实例化以及初始化,销毁需要自行进行调用。
- @Bean指定initMethod和destroyMethod
@Configuration
public class CustomConfig {
@Bean(initMethod = “init”,destroyMethod = “destroy”)
public Person person(){
return new Person();
}
}
相当于xml中配置init-method和destroy-method属性
- 实现InitializingBean和DisposableBean
public class Person implements InitializingBean, DisposableBean {
public Person() {
}
@Override
public void afterPropertiesSet() throws Exception {
}
@Override
public void destroy() throws Exception {
}
}
- 使用@PostConstruct和@PreDestroy
注解使用InitDestroyAnnotationBeanPostProcessor进行解析处理,父类CommonAnnotationBeanPostProcessor
public class Person {
public Person() {
}
@PostConstruct
public void postConstruct(){
}
@PreDestroy
public void preDestroy(){
}
}
BeanPostProcessor
-
postProcessBeforeInitialization 初始化之前执行方法
-
postProcessAfterInitialization 初始化之后执行方法
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
@Configuration
@Import(CustomBeanPostProcessor.class)
public class CustomConfig {
@Bean
public Person person(){
return new Person();
}
}
执行方法若是返回null值,后续的BeanPostProcessor不会进行执行,源代码执行如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
生命周期执行方法顺序、
答:初始化方法执行顺序
-
@PostConstruct
-
实现InitializingBean接口的方法
-
@Bean指定initMethod
销毁方法执行顺序
-
@PreDestroy
-
实现DisposableBean接口的方法
-
@Bean指定destroyMethod
Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:
-
Methods annotated with @PostConstruct
-
afterPropertiesSet() as defined by the InitializingBean callback interface
-
A custom configured init() method
Destroy methods are called in the same order:
-
Methods annotated with @PreDestroy
-
destroy() as defined by the DisposableBean callback interface
-
A custom configured destroy() method
常用注解
@Value
属性进行赋值,可以有如下三种写法
- 直接赋值
public class Person {