写点什么

spring4.1.8 扩展实战之二:Aware 接口揭秘

作者:程序员欣宸
  • 2022 年 6 月 13 日
  • 本文字数:12782 字

    阅读完需:约 42 分钟

spring4.1.8扩展实战之二:Aware接口揭秘

欢迎访问我的 GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • Aware.java 是个没有定义任何方法的接口,拥有众多子接口,在 spring 源码中有多处都在使用这些子接口完成各种场景下的回调操作,当业务有需要时,我们只需创建类来实现相关接口,再声明为 bean,就可以被 spring 容器主动回调;

spring 源码分析 Aware 子类的使用场景

  • 接下来通过分析 spring 源码,我们来看看典型的 Aware 子类有哪些,使用场景是什么?

  • 在 spring 容器初始化过程中,会执行 AbstractApplicationContext 类的 prepareBeanFactory 方法,这里面会创建一个 bean 后置处理器 ApplicationContextAwareProcessor,如下图红框所示:


  • 在 bean 被初始化之前,所有的 bean 后置处理器的 postProcessBeforeInitialization 方法都会被执行,如下图红框所示:


  • 由以上两步可以确定:对于每个 bean 后置处理器来说,它的 postProcessBeforeInitialization 方法会在每个 bean 的初始化之前被调用一次;

  • 来看看 ApplicationContextAwareProcessor 类的 postProcessBeforeInitialization 方法,按照前面的分析,该方法在每个 bean 被初始化之前都会被执行,如下图红框所示,invokeAwareInterfaces 方法会被调用,这是我们要关注的重点:


  • 展开 invokeAwareInterfaces 方法看看:


private void invokeAwareInterfaces(Object bean) {    if (bean instanceof Aware) {      if (bean instanceof EnvironmentAware) {        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());      }      if (bean instanceof EmbeddedValueResolverAware) {        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(            new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));      }      if (bean instanceof ResourceLoaderAware) {        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);      }      if (bean instanceof ApplicationEventPublisherAware) {        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);      }      if (bean instanceof MessageSourceAware) {        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);      }      if (bean instanceof ApplicationContextAware) {        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);      }    }  }
复制代码


  • 从上述代码可以看出,如果当前的 bean 实现了某个接口,那么它的某个对应的方法就会被调用,例如我们创建了一个 bean 实现了 ApplicationContextAware 接口,那么这个 bean 的 setApplicationContext 方法就会被调用,入参是 applicationContext 成员变量,这样我们的 bean 就能得到 applicationContext 对象了;

  • 以上就是 Aware 的接口使用原理:业务按需要实现特定的 Aware 接口,spring 容器会主动找到该 bean,然后调用特定的方法,将特定的参数传递给 bean;

BeanNameAware 接口的调用场景

  • BeanNameAware 也是 Aware 的子接口,不过它的调用场景和前面分析的几个 Aware 子接口不同,并未出现在 ApplicationContextAwareProcessor 类的 invokeAwareInterfaces 方法中,我们来看看它是如何被调用的;

  • 如下图所示,红框中就是 BeanNameAware 接口被调用的地方,而绿框中的 applyBeanPostProcessorsBeforeInitialization 方法就是前面我们分析的那些 Aware 子接口被调用的位置:


  • 方法 invokeAwareMethods 如下所示,和前面的讨论一样,特定类型的 bean,其特定的方法被调用,传入特定的入参:


private void invokeAwareMethods(final String beanName, final Object bean) {    if (bean instanceof Aware) {      if (bean instanceof BeanNameAware) {        ((BeanNameAware) bean).setBeanName(beanName);      }      if (bean instanceof BeanClassLoaderAware) {        ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());      }      if (bean instanceof BeanFactoryAware) {        ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);      }    }  }
复制代码

实战,通过 Aware 接口得到想要的对象

  • 了解 Aware 接口在 spring 环境中的用法之后,我们可以通过实战来验证前面所学了,本次实战我们创建两个类,分别实现 ApplicationContextAware 和 BeanNameAware 这两个接口,看声明的方法是否能被调用,并验证传入的对象是否有效(文章结尾处提供本次实战的工程源码下载);

  • 基于 maven 新建一个 SpringBoot 的 web 工程 customizeaware

  • 新建工具类 Utils,提供静态方法 printTrack 用于打印当前线程堆栈信息:


package com.bolingcavalry.customizeaware.util;

import org.slf4j.Logger;import org.slf4j.LoggerFactory;
/** * @Description : 提供一些常用的工具方法 * @Author : zq2599@gmail.com * @Date : 2018-08-14 05:51 */public class Utils { private static final Logger logger = LoggerFactory.getLogger(Utils.class);
/** * 打印当前线程堆栈信息 * @param prefix */ public static void printTrack(String prefix){ StackTraceElement[] st = Thread.currentThread().getStackTrace();
if(null==st){ logger.info("invalid stack"); return; }
StringBuffer sbf =new StringBuffer();
for(StackTraceElement e:st){ if(sbf.length()>0){ sbf.append(" <- "); sbf.append(System.getProperty("line.separator")); }
sbf.append(java.text.MessageFormat.format("{0}.{1}() {2}" ,e.getClassName() ,e.getMethodName() ,e.getLineNumber())); }
logger.info(prefix + "\n************************************************************\n" + sbf.toString() + "\n************************************************************"); }}
复制代码


  • 新建类 CustomizeBeanNameAware,实现 BeanNameAware 接口,方法 setBeanName 被调用的时候会打印当前堆栈信息:


package com.bolingcavalry.customizeaware.aware;
import com.bolingcavalry.customizeaware.util.Utils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.BeanNameAware;import org.springframework.stereotype.Service;
/** * @Description : * @Author : zq2599@gmail.com * @Date : 2018-08-13 18:55 */@Servicepublic class CustomizeBeanNameAware implements BeanNameAware { private String beanName;
@Override public void setBeanName(String beanName) { Utils.printTrack("beanName is set to " + beanName); this.beanName = beanName; }
public String getBeanName() { return this.beanName; }}
复制代码


  • 新建类 CustomizeApplicationContextAware,实现 ApplicationContextAware 接口,方法 setApplicationContext 被调用的时候会打印当前堆栈信息::


package com.bolingcavalry.customizeaware.aware;
import com.bolingcavalry.customizeaware.util.Utils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Service;
/** * @Description : * @Author : zq2599@gmail.com * @Date : 2018-08-13 19:01 */@Servicepublic class CustomizeApplicationContextAware implements ApplicationContextAware { private ApplicationContext applicationContext;
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Utils.printTrack("applicationContext is set to " + applicationContext); this.applicationContext = applicationContext; }
public ApplicationContext getApplicationContext(){ return this.applicationContext; }}
复制代码


  • 新建一个 Controller,提供 http 服务用于验证 CustomizeBeanNameAware 和 CustomizeApplicationContextAware 这两个 bean,看看它们被 spring 容器设置的 beanName 和 applicationContext 是否可用:


package com.bolingcavalry.customizeaware.controller;
import com.bolingcavalry.customizeaware.aware.CustomizeApplicationContextAware;import com.bolingcavalry.customizeaware.aware.CustomizeBeanNameAware;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
/** * @Description : * @Author : zq2599@gmail.com * @Date : 2018-08-13 19:04 */@RestControllerpublic class HelloWorldController {
@Autowired private CustomizeBeanNameAware customizeBeanNameAware;
@Autowired private CustomizeApplicationContextAware customizeApplicationContextAware;
@RequestMapping("/hello") public String hello(){
String[] beanDefinitionNames = customizeApplicationContextAware.getApplicationContext().getBeanDefinitionNames();
StringBuilder stringBuilder = new StringBuilder();
int arrayLength = 0;
if(null!=beanDefinitionNames){ arrayLength = beanDefinitionNames.length; //将所有bean的名称拼接成字符串(带html的换行符号<br>) for(String name : beanDefinitionNames){ stringBuilder.append(name).append("<br>"); } }
return "hello, " + new Date() + "<br><br>CustomizeBeanNameAware instance bean name : " + customizeBeanNameAware.getBeanName() + "<br><br>bean definition names, size " + arrayLength + ", detail :<br><br>" + stringBuilder; }

}
复制代码


  • 启动应用,看到启动日志中带有 CustomizeBeanNameAware 和 CustomizeApplicationContextAware 的接口方法被调用时输出的日志,并且线程堆栈和我们之前看的 spring 源码位置一致,分别是 ApplicationContextAwareProcessor.invokeAwareInterfaces()和 AbstractAutowireCapableBeanFactory.invokeAwareMethods():


C:\jdk\bin\java.exe -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=63257 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:C:\software\JetBrains\IntelliJIDEA\lib\idea_rt.jar=63258:C:\software\JetBrains\IntelliJIDEA\bin -Dfile.encoding=UTF-8 -classpath C:\jdk\jre\lib\charsets.jar;C:\jdk\jre\lib\deploy.jar;C:\jdk\jre\lib\ext\access-bridge-64.jar;C:\jdk\jre\lib\ext\cldrdata.jar;C:\jdk\jre\lib\ext\dnsns.jar;C:\jdk\jre\lib\ext\jaccess.jar;C:\jdk\jre\lib\ext\jfxrt.jar;C:\jdk\jre\lib\ext\localedata.jar;C:\jdk\jre\lib\ext\nashorn.jar;C:\jdk\jre\lib\ext\sunec.jar;C:\jdk\jre\lib\ext\sunjce_provider.jar;C:\jdk\jre\lib\ext\sunmscapi.jar;C:\jdk\jre\lib\ext\sunpkcs11.jar;C:\jdk\jre\lib\ext\zipfs.jar;C:\jdk\jre\lib\javaws.jar;C:\jdk\jre\lib\jce.jar;C:\jdk\jre\lib\jfr.jar;C:\jdk\jre\lib\jfxswt.jar;C:\jdk\jre\lib\jsse.jar;C:\jdk\jre\lib\management-agent.jar;C:\jdk\jre\lib\plugin.jar;C:\jdk\jre\lib\resources.jar;C:\jdk\jre\lib\rt.jar;D:\github\blog_demos\customizeaware\target\classes;C:\Users\12167\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.0.4.RELEASE\spring-boot-starter-web-2.0.4.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\boot\spring-boot-starter\2.0.4.RELEASE\spring-boot-starter-2.0.4.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\boot\spring-boot\2.0.4.RELEASE\spring-boot-2.0.4.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.0.4.RELEASE\spring-boot-autoconfigure-2.0.4.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.0.4.RELEASE\spring-boot-starter-logging-2.0.4.RELEASE.jar;C:\Users\12167\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\12167\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\12167\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.10.0\log4j-to-slf4j-2.10.0.jar;C:\Users\12167\.m2\repository\org\apache\logging\log4j\log4j-api\2.10.0\log4j-api-2.10.0.jar;C:\Users\12167\.m2\repository\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;C:\Users\12167\.m2\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;C:\Users\12167\.m2\repository\org\yaml\snakeyaml\1.19\snakeyaml-1.19.jar;C:\Users\12167\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.0.4.RELEASE\spring-boot-starter-json-2.0.4.RELEASE.jar;C:\Users\12167\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.9.6\jackson-databind-2.9.6.jar;C:\Users\12167\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;C:\Users\12167\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.9.6\jackson-core-2.9.6.jar;C:\Users\12167\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.6\jackson-datatype-jdk8-2.9.6.jar;C:\Users\12167\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.6\jackson-datatype-jsr310-2.9.6.jar;C:\Users\12167\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.6\jackson-module-parameter-names-2.9.6.jar;C:\Users\12167\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.0.4.RELEASE\spring-boot-starter-tomcat-2.0.4.RELEASE.jar;C:\Users\12167\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.32\tomcat-embed-core-8.5.32.jar;C:\Users\12167\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.32\tomcat-embed-el-8.5.32.jar;C:\Users\12167\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.32\tomcat-embed-websocket-8.5.32.jar;C:\Users\12167\.m2\repository\org\hibernate\validator\hibernate-validator\6.0.11.Final\hibernate-validator-6.0.11.Final.jar;C:\Users\12167\.m2\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;C:\Users\12167\.m2\repository\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;C:\Users\12167\.m2\repository\com\fasterxml\classmate\1.3.4\classmate-1.3.4.jar;C:\Users\12167\.m2\repository\org\springframework\spring-web\5.0.8.RELEASE\spring-web-5.0.8.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\spring-beans\5.0.8.RELEASE\spring-beans-5.0.8.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\spring-webmvc\5.0.8.RELEASE\spring-webmvc-5.0.8.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\spring-aop\5.0.8.RELEASE\spring-aop-5.0.8.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\spring-context\5.0.8.RELEASE\spring-context-5.0.8.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\spring-expression\5.0.8.RELEASE\spring-expression-5.0.8.RELEASE.jar;C:\Users\12167\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\12167\.m2\repository\org\springframework\spring-core\5.0.8.RELEASE\spring-core-5.0.8.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\spring-jcl\5.0.8.RELEASE\spring-jcl-5.0.8.RELEASE.jar com.bolingcavalry.customizeaware.CustomizeawareApplication
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.0.4.RELEASE)
2018-08-14 06:07:11.512 INFO 18940 --- [ main] c.b.c.CustomizeawareApplication : Starting CustomizeawareApplication on DESKTOP-82CCEBN with PID 18940 (D:\github\blog_demos\customizeaware\target\classes started by 12167 in D:\github\blog_demos\customizeaware)2018-08-14 06:07:11.514 INFO 18940 --- [ main] c.b.c.CustomizeawareApplication : No active profile set, falling back to default profiles: default2018-08-14 06:07:11.546 INFO 18940 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6ab7a896: startup date [Tue Aug 14 06:07:11 GMT+08:00 2018]; root of context hierarchy2018-08-14 06:07:12.165 INFO 18940 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)2018-08-14 06:07:12.177 INFO 18940 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]2018-08-14 06:07:12.177 INFO 18940 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.322018-08-14 06:07:12.180 INFO 18940 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\jdk\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\iCLS\;C:\Program Files\Intel\Intel(R) Management Engine Components\iCLS\;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\jdk\bin;C:\software\Git\cmd;C:\software\apache-maven-3.5.0\bin;;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;%SYSTEMROOT%\System32\OpenSSH\;C:\Users\12167\AppData\Local\Microsoft\WindowsApps;;.]2018-08-14 06:07:12.244 INFO 18940 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext2018-08-14 06:07:12.244 INFO 18940 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 700 ms2018-08-14 06:07:12.281 INFO 18940 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]2018-08-14 06:07:12.284 INFO 18940 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]2018-08-14 06:07:12.284 INFO 18940 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]2018-08-14 06:07:12.284 INFO 18940 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]2018-08-14 06:07:12.285 INFO 18940 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]2018-08-14 06:07:12.305 INFO 18940 --- [ main] c.b.customizeaware.util.Utils : applicationContext is set to org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6ab7a896: startup date [Tue Aug 14 06:07:11 GMT+08:00 2018]; root of context hierarchy************************************************************java.lang.Thread.getStackTrace() 1,559 <- com.bolingcavalry.customizeaware.util.Utils.printTrack() 20 <- com.bolingcavalry.customizeaware.aware.CustomizeApplicationContextAware.setApplicationContext() 22 <- org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces() 120 <- org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization() 96 <- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization() 416 <- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean() 1,691 <- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean() 573 <- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean() 495 <- org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0() 317 <- org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton() 222 <- org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean() 315 <- org.springframework.beans.factory.support.AbstractBeanFactory.getBean() 199 <- org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons() 759 <- org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization() 869 <- org.springframework.context.support.AbstractApplicationContext.refresh() 550 <- org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh() 140 <- org.springframework.boot.SpringApplication.refresh() 762 <- org.springframework.boot.SpringApplication.refreshContext() 398 <- org.springframework.boot.SpringApplication.run() 330 <- org.springframework.boot.SpringApplication.run() 1,258 <- org.springframework.boot.SpringApplication.run() 1,246 <- com.bolingcavalry.customizeaware.CustomizeawareApplication.main() 10************************************************************2018-08-14 06:07:12.307 INFO 18940 --- [ main] c.b.customizeaware.util.Utils : beanName is set to customizeBeanNameAware************************************************************java.lang.Thread.getStackTrace() 1,559 <- com.bolingcavalry.customizeaware.util.Utils.printTrack() 20 <- com.bolingcavalry.customizeaware.aware.CustomizeBeanNameAware.setBeanName() 20 <- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods() 1,712 <- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean() 1,686 <- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean() 573 <- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean() 495 <- org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0() 317 <- org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton() 222 <- org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean() 315 <- org.springframework.beans.factory.support.AbstractBeanFactory.getBean() 199 <- org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons() 759 <- org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization() 869 <- org.springframework.context.support.AbstractApplicationContext.refresh() 550 <- org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh() 140 <- org.springframework.boot.SpringApplication.refresh() 762 <- org.springframework.boot.SpringApplication.refreshContext() 398 <- org.springframework.boot.SpringApplication.run() 330 <- org.springframework.boot.SpringApplication.run() 1,258 <- org.springframework.boot.SpringApplication.run() 1,246 <- com.bolingcavalry.customizeaware.CustomizeawareApplication.main() 10************************************************************2018-08-14 06:07:12.359 INFO 18940 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2018-08-14 06:07:12.474 INFO 18940 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6ab7a896: startup date [Tue Aug 14 06:07:11 GMT+08:00 2018]; root of context hierarchy2018-08-14 06:07:12.507 INFO 18940 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello]}" onto public java.lang.String com.bolingcavalry.customizeaware.controller.HelloWorldController.hello()2018-08-14 06:07:12.511 INFO 18940 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)2018-08-14 06:07:12.511 INFO 18940 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)2018-08-14 06:07:12.524 INFO 18940 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2018-08-14 06:07:12.524 INFO 18940 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2018-08-14 06:07:12.602 INFO 18940 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup2018-08-14 06:07:12.622 INFO 18940 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''2018-08-14 06:07:12.625 INFO 18940 --- [ main] c.b.c.CustomizeawareApplication : Started CustomizeawareApplication in 1.311 seconds (JVM running for 1.932)
复制代码


  • 浏览器访问 web 服务,地址:http://localhost:8080/hello,如下图,两个实现了 Aware 接口的 bean 的被设置的信息都打印出来了,都是来自 spring 环境的内容:


  • 验证结束,自定义的 Aware 接口实现类如果声明为 bean,在初始化的时候就会被 spring 容器按照接口类型找出来,通过调用接口方法的方式将特定的对象实例传递给 bean;

实战源码下载

  • 本章实战的源码可以在 github 下载,地址和链接信息如下表所示:



  • 这个 git 项目中有多个文件夹,本章源码在文件夹 customizeaware/下,如下图红框所示:


  • 至此,spring 的 Aware 接口实战就结束了,由于篇幅所限,本章只选择了 BeanNameAware 和 ApplicationContextAware 这两个接口来实战,您可以结合 spring 源码去分析其他 Aware 接口的用处,再在 demo 用去验证它们;

欢迎关注 InfoQ:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

发布于: 2022 年 06 月 13 日阅读数: 52
用户头像

搜索"程序员欣宸",一起畅游Java宇宙 2018.04.19 加入

前腾讯、前阿里员工,从事Java后台工作,对Docker和Kubernetes充满热爱,所有文章均为作者原创,个人Github:https://github.com/zq2599/blog_demos

评论

发布
暂无评论
spring4.1.8扩展实战之二:Aware接口揭秘_Java_程序员欣宸_InfoQ写作社区