赞
踩
BeanFactory是Spring框架中的一个核心接口,它提供了一种灵活的方式来管理Bean,并实现了IoC(控制反转)和DI(依赖注入)等特性,为应用程序提供了灵活、可扩展的对象管理和配置机制。
BeanFactory的特性:
网上有些博主描述BeanFactory与 ApplicationContext是一样的
||
现在一般都用ApplicantContext代替BeanFactory 的说法,其实不一定准确。BeanFactory与 ApplicationContext大部分相同的原因是ApplicationContext是BeanFactory的子接口,所以存在些许区别;具体何时使用需要根据业务的需求合理性选择。
BeanFactory是一个轻量级的Bean容器,适用于资源有限的环境和对性能要求较高的场景;而ApplicationContext是一个功能更加丰富的应用上下文,适用于大多数的应用程序开发。
BeanFactory和ApplicationContext的区别:
由于源码过长,仅仅展示部分源码截图分析,想要深入了解的读者可以自行结合源码解读分析,这里不做过多描述,仅和BeanFactory有关,Bean的生命周期在后续博文会有所提及,本篇不做概述。
本文仅解读BeanFactory接口的主要方法,其它方法读者可自行结合源码解读。BeanFactory
接口主要的方法包括 getBean(String name)
、containsBean(String name)
、isSingleton(String name)
等。
根据给定的条件获取一个Bean对象。
检查是否存在给定名称的Bean 。
用于检查给定名称的Bean是否是单例的,它考虑了单例对象缓存、父级Bean工厂以及Bean定义等因素。
BeanFactory 接口有多个实现类,其中最重要的是 DefaultListableBeanFactory 和 XmlBeanFactory。前者是 Spring 默认的 BeanFactory 实现类,后者是从 XML 文件加载 bean 配置信息的 BeanFactory 实现类。本文只分析DefaultListableBeanFactory 类,想要了解XmlBeanFactory类可以自行结合源码分析。
DefaultListableBeanFactory 类是 BeanFactory 接口的默认实现,负责管理 bean 的注册、解析、依赖注入等工作。
用于注册Bean定义。
获取指定类型的 Bean。
BeanFactory负责管理Bean的生命周期,其具体操作和控制逻辑:
上文1.2 - 3
有解释[先预判一下你们的预判,我相信有细心的读者看完下面的Demo,就会来说怎么博主使用了@Autowired
,请看Demo下的ps
有解释哈])。使用BeanFactory管理Bean的生命周期,接口实现Demo:
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
/**
* 实现了 InitializingBean 和 DisposableBean 接口,分别用于在Bean初始化和销毁时执行特定的逻辑
*/
@Component
class MyBean implements InitializingBean, DisposableBean {
private String message;
public MyBean() {
System.out.println("Bean实例化");
}
/**
* 通过 @Autowired 注解的 setMessage 方法进行注入
*/
@Autowired
public void setMessage(String message) {
this.message = message;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Bean初始化: " + message);
}
@Override
public void destroy() throws Exception {
System.out.println("Bean销毁");
}
}
/**
* 实现了 BeanFactoryPostProcessor 接口,用于在BeanFactory标准初始化之后修改应用程序上下文的内部bean工厂
*/
@Component
class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
/**
* BeanFactory 后置处理器是在 BeanFactory 标准初始化之后、在所有其他 bean 被实例化之前执行的
* 意味着,在容器启动时,首先会初始化 BeanFactory,然后才会执行任何 BeanFactory 后置处理器的逻辑,包括自定义的 BeanFactory 后置处理器
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
System.out.println("自定义BeanFactory后置处理器");
}
}
public class Demo {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Demo.class);
MyBean myBean = context.getBean(MyBean.class);
myBean.setMessage("Hello, Spring!");
context.close();
}
}
/**
* 输出结果:
* 自定义BeanFactory后置处理器
Bean实例化
Bean初始化: Hello, Spring!
Bean销毁
* 原因:
* 1、AnnotationConfigApplicationContext 会创建并初始化 BeanFactory,然后执行所有的 BeanFactoryPostProcessor,所以首先输出 “自定义BeanFactory后置处理器”。
2、Spring 容器会创建 MyBean 的实例,并输出 “Bean实例化”。
3、在 MyBean 实例化之后,Spring 容器会通过 @Autowired 注解注入 message 属性,并调用 afterPropertiesSet() 方法,输出 “Bean初始化: Hello, Spring!”。
4、当调用 context.close() 方法时,Spring 容器会销毁 MyBean 的实例,并调用 destroy() 方法,输出 “Bean销毁”。
*/
ps: AnnotationConfigApplicationContext
是 BeanFactory
接口的一个具体实现,同时也是 ApplicationContext
接口的一个子接口,它提供了对 @Autowired
注解的支持。
BeanFactory 能够通过读取配置文件或者注解等方式,将 bean 实例化并管理起来,并且解决它们之间的依赖关系,确保各个 bean 能够正确初始化和销毁。
使用 Spring 的 BeanFactory 实现依赖注入Demo:
/**
* message 属性和相应的 setter 和 getter 方法
*/
public class MyBean {
private String message;
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
public interface MyBeanFactory {
MyBean getMyBean();
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactoryImpl implements MyBeanFactory {
private final MyBean myBean;
/**
* 构造函数注入来获取MyBean实例,并将其保存在BeanFactory中
*/
@Autowired
public MyBeanFactoryImpl(MyBean myBean) {
this.myBean = myBean;
}
@Override
public MyBean getMyBean() {
return myBean;
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* MyDemo 类使用了 @Component 注解,表明它是一个Spring的组件,并且在其中注入了 MyBeanFactory 的实例。Spring在启动时会扫描这个类,并创建它的实例,并通过构造函数注入的方式将 MyBeanFactory 的实例传递给 MyDemo 类
*/
@Component
public class MyDemo {
private final MyBeanFactory myBeanFactory;
/**
* 通过构造函数注入的方式获取了 MyBeanFactory 的实例
*/
@Autowired
public MyDemo(MyBeanFactory myBeanFactory) {
this.myBeanFactory = myBeanFactory;
}
public void run() {
// 获取 MyBean 实例,并设置消息内容并输出
MyBean myBean = myBeanFactory.getMyBean();
myBean.setMessage("Hello, BeanFactory!");
System.out.println(myBean.getMessage());
}
}
当在 AOP(面向切面编程)中使用 BeanFactory
时,它的作用主要是负责管理切面(Aspect)以及它们所需的各种对象(通常是通知(Advice)和切点(Pointcut))。
实现 AOP,并实现切面的注入和切点的定义Demo:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* 定义切面 MyAspect,并在someMethod()方法执行之前打印一条日志
*/
@Aspect
@Component
public class MyAspect {
@Before("execution(* com.example.MyBean.someMethod())")
public void beforeSomeMethod() {
System.out.println("Before executing someMethod()");
}
}
切点是一个表达式,它决定了切面将会在哪些连接点(方法调用、方法执行、异常处理等)被触发。在这里,将切点定义为 MyBean
类中的 someMethod()
方法。
execution(* com.example.MyBean.someMethod())
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactoryImpl implements MyBeanFactory {
private final MyBean myBean;
/**
* 注入了MyBean类的实例,这个实例可能会被切面拦截
*/
@Autowired
public MyBeanFactoryImpl(MyBean myBean) {
this.myBean = myBean;
}
@Override
public MyBean getMyBean() {
return myBean;
}
}
要启用 Spring 的 AOP 功能,需要在配置中启用 @EnableAspectJAutoProxy
注解。
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
// 其他配置...
}
人生在勤,不索何获
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。