Spring Aware接口()-spring
Spring Aware接口()
Aware
adj. 知道的,明白的,察觉到的,意识到的
adj. 知道的,明白的,察觉到的,意识到的
作用:
当Spring容器创建的bean对象在进行具体操作的时候,如果需要容器的其他对象,此时可以将对象实现Aware接口,来满足当前的需要
作用:
当Spring容器创建的bean对象在进行具体操作的时候,如果需要容器的其他对象,此时可以将对象实现Aware接口,来满足当前的需要
package com.example.zylspringboot.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class ZYLAwareTest implements ApplicationContextAware, BeanNameAware, EnvironmentAware, InitializingBean {
private static ApplicationContext context;
private static String name;
private static Environment env;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
@Override
public void setBeanName(String s) {
name = s;
}
@Override
public void setEnvironment(Environment environment) {
env = environment;
}
public void show(){
log.info("ZYLAwareTest-->context:{},name:{},env:{}",context,name,env);
}
@Override
public void afterPropertiesSet() throws Exception {
this.show();
}
}
console:
2022-11-30 10:41:21.767 INFO 12408 — [ main] c.e.zylspringboot.util.ZYLAwareTest : ZYLAwareTest–>context:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4535b6d5, started on Wed Nov 30 10:41:15 CST 2022,name:ZYLAwareTest,env:ApplicationServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name=’configurationProperties’}, SimpleCommandLinePropertySource {name=’commandLineArgs’}, StubPropertySource {name=’servletConfigInitParams’}, ServletContextPropertySource {name=’servletContextInitParams’}, PropertiesPropertySource {name=’systemProperties’}, OriginAwareSystemEnvironmentPropertySource {name=’systemEnvironment’}, RandomValuePropertySource {name=’random’}, OriginTrackedMapPropertySource {name=’Config resource ‘class path resource [application.properties]’ via location ‘optional:classpath:/”}]}
console:
2022-11-30 10:41:21.767 INFO 12408 — [ main] c.e.zylspringboot.util.ZYLAwareTest : ZYLAwareTest–>context:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4535b6d5, started on Wed Nov 30 10:41:15 CST 2022,name:ZYLAwareTest,env:ApplicationServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name=’configurationProperties’}, SimpleCommandLinePropertySource {name=’commandLineArgs’}, StubPropertySource {name=’servletConfigInitParams’}, ServletContextPropertySource {name=’servletContextInitParams’}, PropertiesPropertySource {name=’systemProperties’}, OriginAwareSystemEnvironmentPropertySource {name=’systemEnvironment’}, RandomValuePropertySource {name=’random’}, OriginTrackedMapPropertySource {name=’Config resource ‘class path resource [application.properties]’ via location ‘optional:classpath:/”}]}
tips:
可是注解都可以实现上面的三种方法,为什么还需要自己手动实现呢?
@Autowired
- @Autowired的解析是需要用到bean的后处理器,属于扩展功能
- 而Aware接口属于内置功能,不加任何扩展,Spring就能识别
- 内置的注入和初始化不受扩展功能的影响,总会被执行
源码:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
//look at me
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = this.getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
}
Aware
adj. 知道的,明白的,察觉到的,意识到的
adj. 知道的,明白的,察觉到的,意识到的
作用:
当Spring容器创建的bean对象在进行具体操作的时候,如果需要容器的其他对象,此时可以将对象实现Aware接口,来满足当前的需要
作用:
当Spring容器创建的bean对象在进行具体操作的时候,如果需要容器的其他对象,此时可以将对象实现Aware接口,来满足当前的需要
package com.example.zylspringboot.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class ZYLAwareTest implements ApplicationContextAware, BeanNameAware, EnvironmentAware, InitializingBean {
private static ApplicationContext context;
private static String name;
private static Environment env;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
@Override
public void setBeanName(String s) {
name = s;
}
@Override
public void setEnvironment(Environment environment) {
env = environment;
}
public void show(){
log.info("ZYLAwareTest-->context:{},name:{},env:{}",context,name,env);
}
@Override
public void afterPropertiesSet() throws Exception {
this.show();
}
}
console:
2022-11-30 10:41:21.767 INFO 12408 — [ main] c.e.zylspringboot.util.ZYLAwareTest : ZYLAwareTest–>context:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4535b6d5, started on Wed Nov 30 10:41:15 CST 2022,name:ZYLAwareTest,env:ApplicationServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name=’configurationProperties’}, SimpleCommandLinePropertySource {name=’commandLineArgs’}, StubPropertySource {name=’servletConfigInitParams’}, ServletContextPropertySource {name=’servletContextInitParams’}, PropertiesPropertySource {name=’systemProperties’}, OriginAwareSystemEnvironmentPropertySource {name=’systemEnvironment’}, RandomValuePropertySource {name=’random’}, OriginTrackedMapPropertySource {name=’Config resource ‘class path resource [application.properties]’ via location ‘optional:classpath:/”}]}
console:
2022-11-30 10:41:21.767 INFO 12408 — [ main] c.e.zylspringboot.util.ZYLAwareTest : ZYLAwareTest–>context:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4535b6d5, started on Wed Nov 30 10:41:15 CST 2022,name:ZYLAwareTest,env:ApplicationServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name=’configurationProperties’}, SimpleCommandLinePropertySource {name=’commandLineArgs’}, StubPropertySource {name=’servletConfigInitParams’}, ServletContextPropertySource {name=’servletContextInitParams’}, PropertiesPropertySource {name=’systemProperties’}, OriginAwareSystemEnvironmentPropertySource {name=’systemEnvironment’}, RandomValuePropertySource {name=’random’}, OriginTrackedMapPropertySource {name=’Config resource ‘class path resource [application.properties]’ via location ‘optional:classpath:/”}]}
tips:
可是注解都可以实现上面的三种方法,为什么还需要自己手动实现呢?
@Autowired
- @Autowired的解析是需要用到bean的后处理器,属于扩展功能
- 而Aware接口属于内置功能,不加任何扩展,Spring就能识别
- 内置的注入和初始化不受扩展功能的影响,总会被执行
源码:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
//look at me
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = this.getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
}