宝安网站设计排名,网站商城首页怎么做吸引人,免费网站推荐软件,深圳做分销网站建设目录 Aware接口概述为什么需要Aware接口 InitializingBean接口Autoware失效分析 Aware接口
概述
在Spring框架中#xff0c;Aware 接口是一种常用的设计模式#xff0c;用于允许bean在初始化时感知#xff08;或获取#xff09;Spring容器中的某些资源或环境信息。这些接… 目录 Aware接口概述为什么需要Aware接口 InitializingBean接口Autoware失效分析 Aware接口
概述
在Spring框架中Aware 接口是一种常用的设计模式用于允许bean在初始化时感知或获取Spring容器中的某些资源或环境信息。这些接口通常以 ...Aware 结尾并且Spring提供了许多这样的接口。以下是一些常见的 Aware 接口及其用途
BeanNameAware 允许bean获取其在Spring容器中的名称。实现此接口的bean可以通过 setBeanName(String name) 方法设置其名称。 BeanFactoryAware 允许bean获取对其创建它的 BeanFactory 的引用。实现此接口的bean可以通过 setBeanFactory(BeanFactory beanFactory) 方法设置其 BeanFactory。 ApplicationContextAware 允许bean获取对其运行时的 ApplicationContext 的引用。实现此接口的bean可以通过 setApplicationContext(ApplicationContext applicationContext) 方法设置其 ApplicationContext。 ResourceLoaderAware 允许bean获取 ResourceLoader它可以用来加载类路径上的资源。实现此接口的bean可以通过 setResourceLoader(ResourceLoader resourceLoader) 方法设置其 ResourceLoader。 MessageSourceAware 允许bean获取 MessageSource它用于国际化消息解析。实现此接口的bean可以通过 setMessageSource(MessageSource messageSource) 方法设置其 MessageSource。 ApplicationEventPublisherAware 允许bean获取 ApplicationEventPublisher它用于发布应用事件。实现此接口的bean可以通过 setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) 方法设置其 ApplicationEventPublisher。 EnvironmentAware 允许bean获取 Environment它提供了对应用程序运行时的环境属性的访问。实现此接口的bean可以通过 setEnvironment(Environment environment) 方法设置其 Environment。
使用这些 Aware 接口Spring bean可以在其生命周期的早期阶段获取到所需的资源或服务然后利用这些资源或服务执行其逻辑。例如ApplicationContextAware 允许一个bean访问整个应用上下文这可能对于查找其他bean或资源非常有用。
要实现这些接口你只需要在你的bean类中添加相应的 set 方法并在Spring配置中声明这个bean。Spring容器会自动调用这些 set 方法并传递相应的资源或服务。
例如要实现 ApplicationContextAware你可以这样做
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; Component
public class MyBean implements ApplicationContextAware { private ApplicationContext applicationContext; Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext applicationContext; } public ApplicationContext getApplicationContext() { return applicationContext; }
}在这个例子中MyBean 实现了 ApplicationContextAware 接口并通过 setApplicationContext 方法获取了 ApplicationContext 的引用。然后这个bean就可以使用 applicationContext 属性来访问Spring容器中的其他bean或服务了。
为什么需要Aware接口
有了Autoware注解为什么还需要 Aware 接口
因为Aware接口提供了一种机制让bean能够在Spring容器初始化它们的过程中获取到额外的信息或资源这些信息或资源可能无法通过简单的依赖注入来获取。Autowired 的解析需要用到 bean 后处理器, 属于扩展功能 而 Aware 接口属于内置功能, 不加任何扩展, Spring 就能识别。某些情况下, 扩展功能会失效, 而内置功能不会失效。Aware接口提供了一种更灵活的方式来获取资源因为它们可以在bean的初始化过程中任何时候被调用。相比之下依赖注入通常发生在bean创建的过程中并且受到Spring容器管理的依赖关系的限制。虽然可以通过Autowired直接注入ApplicationContext但这可能会增加代码的耦合度因为任何需要访问ApplicationContext的类都必须依赖它。使用ApplicationContextAware接口可以让这种依赖更加显式并且可以通过实现接口来控制哪些类实际上需要这种依赖。
InitializingBean接口
InitializingBean接口是Spring框架中的一个回调接口它定义了一个afterPropertiesSet()方法。这允许bean在依赖注入完成后执行一些初始化逻辑。当一个bean的所有属性都被Spring容器通过依赖注入设置完毕之后afterPropertiesSet()方法会被自动调用。
实现InitializingBean接口的bean可以在afterPropertiesSet()方法中编写自定义的初始化代码。通常用于执行一些在依赖注入后必须执行的设置或准备操作。这使得bean可以在其属性被设置之后执行一些初始化逻辑。
下面是一个实现InitializingBean接口的简单例子
import org.springframework.beans.factory.InitializingBean; public class MyBean implements InitializingBean { private String someProperty; public void setSomeProperty(String someProperty) { this.someProperty someProperty; } Override public void afterPropertiesSet() throws Exception { // 初始化逻辑这将在所有属性被设置之后执行 System.out.println(Properties have been set on the bean. Initializing...); // 例如可以在这里进行资源加载、数据初始化等操作 } public void doSomething() { // 业务逻辑 }
}在这个例子中MyBean 类实现了 InitializingBean 接口并覆盖了 afterPropertiesSet() 方法。当 Spring 容器创建 MyBean 的实例并设置其所有属性之后它会调用 afterPropertiesSet() 方法。
虽然InitializingBean接口提供了一种通用的初始化机制但Spring也支持使用PostConstruct注解作为替代。
InitializingBean接口的使用不是强制性的。Spring也允许通过在XML配置文件中使用bean元素的init-method属性或者在注解配置中使用PostConstruct注解来指定初始化方法。PostConstruct注解的方法会在依赖注入完成后自动被调用这与afterPropertiesSet()方法的效果相同但它是Java EE提供的替代InitializingBean接口的方式来执行初始化逻辑。
此外你还可以通过实现DisposableBean接口并提供destroy()方法的实现来定义bean销毁时的逻辑。当bean不再需要并被Spring容器销毁时destroy()方法会被自动调用。这类似于InitializingBean接口但用于bean生命周期的结束阶段。
Autoware失效分析
看下面一个例子
配置类
package com.cys.demo02.Chapter06;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.annotation.PostConstruct;Configuration
public class MyConfig {private static final Logger log LoggerFactory.getLogger(MyConfig.class);Autowiredpublic void setApplicationContext(ApplicationContext applicationContext) {log.debug(注入 ApplicationContext);}PostConstructpublic void init() {log.debug(初始化);}}测试类
package com.cys.demo02.Chapter06;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;public class TestAutowiredInvalidated {private static final Logger log LoggerFactory.getLogger(TestAutowiredInvalidated.class);public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();context.registerBean(myConfig1, MyConfig.class);context.registerBean(AutowiredAnnotationBeanPostProcessor.class);context.registerBean(CommonAnnotationBeanPostProcessor.class);context.registerBean(ConfigurationClassPostProcessor.class);context.refresh();context.close();}
}运行后可以正常打印出依赖注入时打印的信息
12:43:34.799 [main] DEBUG com.cys.demo02.Chapter06.MyConfig - 注入 ApplicationContext
12:43:34.800 [main] DEBUG com.cys.demo02.Chapter06.MyConfig - 初始化但是当我们给配置类增加一个BeanFactoryPostProcessor如下
package com.cys.demo02.Chapter06;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.annotation.PostConstruct;Configuration
public class MyConfig {private static final Logger log LoggerFactory.getLogger(MyConfig.class);Autowiredpublic void setApplicationContext(ApplicationContext applicationContext) {log.debug(注入 ApplicationContext);}PostConstructpublic void init() {log.debug(初始化);}Bean //添加一个beanFactory的后处理器public BeanFactoryPostProcessor processor1(){return configurableListableBeanFactory - {log.debug(执行processor1);};}}运行后发现未打印出依赖注入时打印的信息。这是为什么呢
Java 配置类不包含 BeanFactoryPostProcessor 的情况 #mermaid-svg-O3DOmSH9hXkwD2ky {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-O3DOmSH9hXkwD2ky .error-icon{fill:#552222;}#mermaid-svg-O3DOmSH9hXkwD2ky .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-O3DOmSH9hXkwD2ky .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-O3DOmSH9hXkwD2ky .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-O3DOmSH9hXkwD2ky .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-O3DOmSH9hXkwD2ky .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-O3DOmSH9hXkwD2ky .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-O3DOmSH9hXkwD2ky .marker{fill:#333333;stroke:#333333;}#mermaid-svg-O3DOmSH9hXkwD2ky .marker.cross{stroke:#333333;}#mermaid-svg-O3DOmSH9hXkwD2ky svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-O3DOmSH9hXkwD2ky .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-O3DOmSH9hXkwD2ky text.actortspan{fill:black;stroke:none;}#mermaid-svg-O3DOmSH9hXkwD2ky .actor-line{stroke:grey;}#mermaid-svg-O3DOmSH9hXkwD2ky .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-O3DOmSH9hXkwD2ky .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-O3DOmSH9hXkwD2ky #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-O3DOmSH9hXkwD2ky .sequenceNumber{fill:white;}#mermaid-svg-O3DOmSH9hXkwD2ky #sequencenumber{fill:#333;}#mermaid-svg-O3DOmSH9hXkwD2ky #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-O3DOmSH9hXkwD2ky .messageText{fill:#333;stroke:#333;}#mermaid-svg-O3DOmSH9hXkwD2ky .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-O3DOmSH9hXkwD2ky .labelText,#mermaid-svg-O3DOmSH9hXkwD2ky .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-O3DOmSH9hXkwD2ky .loopText,#mermaid-svg-O3DOmSH9hXkwD2ky .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-O3DOmSH9hXkwD2ky .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-O3DOmSH9hXkwD2ky .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-O3DOmSH9hXkwD2ky .noteText,#mermaid-svg-O3DOmSH9hXkwD2ky .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-O3DOmSH9hXkwD2ky .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-O3DOmSH9hXkwD2ky .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-O3DOmSH9hXkwD2ky .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-O3DOmSH9hXkwD2ky .actorPopupMenu{position:absolute;}#mermaid-svg-O3DOmSH9hXkwD2ky .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-O3DOmSH9hXkwD2ky .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-O3DOmSH9hXkwD2ky .actor-man circle,#mermaid-svg-O3DOmSH9hXkwD2ky line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-O3DOmSH9hXkwD2ky :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ApplicationContext BeanFactoryPostProcessor BeanPostProcessor Java配置类 1. 执行 BeanFactoryPostProcessor 2. 注册 BeanPostProcessor 3. 创建和初始化 3.1 依赖注入扩展(如 Value 和 Autowired) 3.2 初始化扩展(如 PostConstruct) 3.3 执行 Aware 及 InitializingBean 3.4 创建成功 ApplicationContext BeanFactoryPostProcessor BeanPostProcessor Java配置类 Java 配置类包含 BeanFactoryPostProcessor 的情况因为要创建其中的 BeanFactoryPostProcessor 必须提前创建 Java 配置类而此时的 BeanPostProcessor 还未准备好导致 Autowired 等注解失效 #mermaid-svg-ouIZKYM1jh3UIoRN {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ouIZKYM1jh3UIoRN .error-icon{fill:#552222;}#mermaid-svg-ouIZKYM1jh3UIoRN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ouIZKYM1jh3UIoRN .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-ouIZKYM1jh3UIoRN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ouIZKYM1jh3UIoRN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ouIZKYM1jh3UIoRN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ouIZKYM1jh3UIoRN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ouIZKYM1jh3UIoRN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ouIZKYM1jh3UIoRN .marker.cross{stroke:#333333;}#mermaid-svg-ouIZKYM1jh3UIoRN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ouIZKYM1jh3UIoRN .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ouIZKYM1jh3UIoRN text.actortspan{fill:black;stroke:none;}#mermaid-svg-ouIZKYM1jh3UIoRN .actor-line{stroke:grey;}#mermaid-svg-ouIZKYM1jh3UIoRN .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-ouIZKYM1jh3UIoRN .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-ouIZKYM1jh3UIoRN #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-ouIZKYM1jh3UIoRN .sequenceNumber{fill:white;}#mermaid-svg-ouIZKYM1jh3UIoRN #sequencenumber{fill:#333;}#mermaid-svg-ouIZKYM1jh3UIoRN #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-ouIZKYM1jh3UIoRN .messageText{fill:#333;stroke:#333;}#mermaid-svg-ouIZKYM1jh3UIoRN .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ouIZKYM1jh3UIoRN .labelText,#mermaid-svg-ouIZKYM1jh3UIoRN .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-ouIZKYM1jh3UIoRN .loopText,#mermaid-svg-ouIZKYM1jh3UIoRN .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-ouIZKYM1jh3UIoRN .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-ouIZKYM1jh3UIoRN .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-ouIZKYM1jh3UIoRN .noteText,#mermaid-svg-ouIZKYM1jh3UIoRN .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-ouIZKYM1jh3UIoRN .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ouIZKYM1jh3UIoRN .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ouIZKYM1jh3UIoRN .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ouIZKYM1jh3UIoRN .actorPopupMenu{position:absolute;}#mermaid-svg-ouIZKYM1jh3UIoRN .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-ouIZKYM1jh3UIoRN .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ouIZKYM1jh3UIoRN .actor-man circle,#mermaid-svg-ouIZKYM1jh3UIoRN line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-ouIZKYM1jh3UIoRN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ApplicationContext BeanFactoryPostProcessor BeanPostProcessor Java配置类 3. 创建和初始化 3.1 执行 Aware 及 InitializingBean 3.2 创建成功 1. 执行 BeanFactoryPostProcessor 2. 注册 BeanPostProcessor ApplicationContext BeanFactoryPostProcessor BeanPostProcessor Java配置类 对应代码
Configuration
public class MyConfig1 {private static final Logger log LoggerFactory.getLogger(MyConfig1.class);Autowiredpublic void setApplicationContext(ApplicationContext applicationContext) {log.debug(注入 ApplicationContext);}PostConstructpublic void init() {log.debug(初始化);}Bean // 注释或添加 beanFactory 后处理器对应上方两种情况public BeanFactoryPostProcessor processor1() {return beanFactory - {log.debug(执行 processor1);};}}解决方法
用内置依赖注入和初始化取代扩展依赖注入和初始化也就是我们前面说的Aware接口用静态工厂方法代替实例工厂方法避免工厂对象提前被创建