Spring Aware介面
Aware
adj. 知道的,明白的,察覺到的,意識到的
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:/''}]}
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); } } }