首页 > 其他分享 >【Spring Bean的生命周期】

【Spring Bean的生命周期】

时间:2023-09-14 10:35:48浏览次数:25  
标签:初始化 生命周期 Spring bean Bean MyBean public

Spring Bean的生命周期

Spring Bean的生命周期分为四个阶段:实例化、属性赋值、初始化和销毁。

实例化

构造器实例化

通过Java类的构造函数实例化Bean,利用Java反射机制,调用bean对应类的构造方法进行实例化。

在XML文件中,可以使用标签的class属性指定要实例化的Bean类。当容器启动时,容器会根据class属性的全限定类名使用反射机制实例化Bean。示例代码:

<bean id="myBean" class="com.example.MyBean"/>

在注解方式中,@Component、@Service、@Controller等注解本质上是Java类的元数据,Spring框架在启动时会扫描指定包路径下所有的类,将被标注了这些注解的类通过反射机制实例化,并将实例化后的对象注册到Spring容器中,以供程序使用。例如:

@Component
public class MyBean {
    // class implementation
}

工厂方法实例化

在Spring配置文件中,可以定义一个工厂类,该工厂类中有一个静态方法可以创建Bean对象,并且可以指定返回值和参数,Spring框架会在启动时自动调用该静态方法来创建Bean对象。这种方式类似于单例模式,因为每个Bean对象只会被实例化一次,并且可以在整个应用程序中共享。配置示例代码如下:

<bean id="myBean" class="com.example.MyBeanFactory" factory-method="createMyBean"/>

代码如下:

public class MyBeanFactory {
    public static MyBean createMyBean() {
        return new MyBean();
    }
}

属性赋值

属性赋值是在实例化Bean后通过BeanPostProcessor接口实现对Bean的属性赋值。

XML方式

在XML文件中定义Bean以及其属性的值来配置Bean,在Spring容器启动时,会解析这些XML文件并根据其定义的配置创建相应的Bean实例。Spring框架提供BeanPostProcessor接口中的postProcessBeforeInitialization()方法会在Bean创建完成后被调用,它可以完成对Bean进行一些额外的处理,例如对属性进行赋值等操作。它会返回一个新的Bean实例,或者修改原始的Bean实例。

注解方式

使用@Autowired或@Value注解进行属性赋值。这些注解的实现原理也是基于BeanPostProcessor接口实现的。

@Autowired注解是根据属性的类型来进行自动注入的,如果Spring容器中存在该类型的Bean,则会自动将其注入到对应的属性中。如果存在多个同类型的Bean,则可以使用@Qualifier注解来指定要注入的Bean的名称。

@Value注解则是根据属性的值来进行注入的,可以使用${}或#{ }来引用配置文件中的属性值,也可以直接指定一个固定的值。

@Value("${jdbc.url}")
private String url;

通过@Value注解,Spring会将配置文件中名为"jdbc.url"的属性值注入到url属性中。

初始化

初始化是Spring Bean生命周期的第三个阶段,它包括两个过程:初始化前和初始化后,BeanPostProcessor接口在执行初始化方法之前和之后定义了两个方法:postProcessBeforeInitialization()和postProcessAfterInitialization()。

postProcessBeforeInitialization()方法在执行Bean的初始化方法之前被调用,可以对Bean进行自定义的前处理操作。例如,可以修改Bean的属性值、增加一些代理逻辑等等。这时的Bean还没有执行初始化方法,也就是说Bean还没有完全初始化。这个方法常常用于注册一些事件监听器、给Bean进行数据校验等。

postProcessAfterInitialization()方法在执行Bean的初始化方法之后被调用,可以对Bean进行自定义的后处理操作。例如,可以对Bean做一些额外的检查、修改某些属性值等等。这时的Bean已经执行了初始化方法,并且已经完全初始化。这个方法常常用于增强Bean的能力或者为Bean提供一些额外服务(如数据缓存、资源池等)。

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //在Bean的初始化方法之前执行的自定义操作
        if (bean instanceof MyBean) {
        	((MyBean)bean).setProperty("new value");
			//注册事件监听器
			if (bean instanceof MyBean) {
				MyBean myBean = (MyBean) bean;
				myBean.addEventListener(new MyEventListener());
			}
			
			//给Bean进行数据校验
			if (bean instanceof MyBean) {
				MyBean myBean = (MyBean) bean;
				Validator validator = new MyBeanValidator();
				validator.validate(myBean);
			}
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //在Bean的初始化方法之后执行的自定义操作
        if (bean instanceof MyBean) {
            //增强Bean的能力
            //检查
			if (bean instanceof MyBean) {
			    MyBean myBean = (MyBean)bean;
			    if (myBean.getName() == null) {
			        throw new IllegalArgumentException("Name cannot be null");
			    }
			}
			//修改某些属性值
			if (bean instanceof MyBean) {
			    MyBean myBean = (MyBean)bean;
			    myBean.setProperty("new value");
			}
			//数据缓存
			if (bean instanceof MyBean) {
			    MyBean myBean = (MyBean)bean;
			    CacheManager cacheMgr = CacheManager.getInstance();
			    Cache cache = cacheMgr.getCache("myCache");
			    cache.put(myBean.getId(), myBean);
			}
			//资源池
			if (bean instanceof MyBean) {
			    MyBean myBean = (MyBean)bean;
			    ConnectionPool pool = ConnectionPool.getInstance();
			    myBean.setConnection(pool.getConnection());
			}
            
        }
        return bean;
    }
}

Spring容器在创建Bean实例之后,会自动调用InitializingBean接口的afterPropertiesSet()方法完成Bean的初始化。

以下是一个实现InitializingBean接口的示例代码:

import org.springframework.beans.factory.InitializingBean;

public class MyBean implements InitializingBean {

    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 在这里初始化Bean
        System.out.println("Initializing MyBean...");
        System.out.println("MyBean message: " + message);
    }
}

在XML配置文件中配置该Bean的属性和初始化方法:

<bean id="myBean" class="com.example.MyBean">
    <property name="message" value="Hello, World!"/>
    <property name="initMethod" value="afterPropertiesSet"/>
</bean>

在上面的配置中,我们设置了Bean的属性message为“Hello, World!”,并设置了initMethod属性为afterPropertiesSet,这样在Bean创建完成后,会自动调用MyBean实现的afterPropertiesSet()方法完成Bean的初始化。

除了实现InitializingBean接口,还可以通过@Bean注解中的initMethod属性,或者使用@PostConstruct注解标注的初始化方法。示例代码:

  1. 通过@Bean注解定义的初始化方法
@Configuration
public class AppConfig {
    @Bean(initMethod = "init")
    public MyBean myBean() {
        return new MyBean();
    }
}

public class MyBean {
    public void init() {
        // initialization code
    }
}
  1. 使用@PostConstruct注解标注的初始化方法
public class MyBean {
    @PostConstruct
    public void init() {
        // initialization code
    }
}

销毁

销毁是Spring Bean生命周期的最后一个阶段,它是通过实现DisposableBean接口或通过配置destroy-method方法来实现。实现DisposableBean接口,需要实现destroy()方法,该方法会在Bean销毁前被调用。在容器关闭之前,Spring会先销毁Bean,并回调Bean的destroy()方法。

在XML文件中,可以使用destroy-method属性指定Bean的销毁方法。Spring容器会在销毁Bean之前调用这个方法。

下面是通过配置destroy-method方法来销毁Bean的示例代码:

<bean id="exampleBean" class="com.example.ExampleBean" destroy-method="cleanup">
    <property name="name" value="John" />
</bean>

在上面的代码中,ExampleBean类有一个名为cleanup的方法,它将在Bean销毁时被调用。在XML文件中,通过配置destroy-method属性来指定销毁方法。

通过实现DisposableBean接口,Bean类可以在调用destroy()方法之前实现销毁操作。该方法会在Bean销毁之前调用。销毁的具体过程可以自定义实现。在销毁Bean之前,需要先关闭应用上下文,释放Bean占用的资源。

下面是通过实现DisposableBean接口来销毁Bean的示例代码:

public class ExampleBean implements DisposableBean {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("Cleaning up resources for " + name);
    }
}

在上面的代码中,ExampleBean类实现了DisposableBean接口,并重写了destroy()方法。在该方法中,可以自定义销毁Bean的逻辑。在Bean销毁之前,Spring容器会回调该方法。

标签:初始化,生命周期,Spring,bean,Bean,MyBean,public
From: https://blog.51cto.com/liaozhiweiblog/7467967

相关文章

  • 【Spring boot】数据库依赖
    如果依赖库不存在,maven安装依赖库JDBC的依赖项:spring-jdbc<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.14</version></dependency>  MySQL连接的依赖项:mysql......
  • Node.js vs. Spring Boot:Hello World 性能对决,谁更快一点?
    前言:SpringBoot在Java生态中备受欢迎,它是一款基于Java构建的轻量级服务端框架,主要用于Web服务。SpringBoot的应用使得创建各类基于Spring的企业级应用变得异常简单。Node.js作为一种基于ChromeV8引擎的JavaScript运行时环境,在服务端上运行JavaScript代码。它以其独......
  • SpringMVC报错:HTTP Status 405 - JSPs only permit GET POST or HEAD
    错误描述如果项目是运行在Tomcat8及以上版本,浏览器发出的PUT请求和DELETE请求可以被页面控制器(Controller)成功接收到,但是返回JSP页面则会报HTTP405的错误提示:"消息JSP只允许GET、POST或HEAD。Jasper还允许OPTIONS"。原因分析原因是Tomcat按照JCP规范(JSP......
  • Spring - DI 依赖注入和 IoC 容器
    前言先理解DI依赖注入再理解Ioc容器更好,不应该先理解IoC容器再理解DI依赖注入。这两个东西必须要放在一起讲,但是又要分好顺序去理解。理解之前不能先看概念,非常地抽象,应该从“为什么”起理解。总而言之,这个两个东西的出现是为了降低程序的耦合度。DI依赖注入Java里......
  • springcloud相关面试题
    (目录)springcloud相关面试题springcloud中网关起什么作用在SpringCloud中,网关起到了路由和过滤的作用。路由:网关通过配置路由规则,将请求转发到不同的服务实例上。它可以根据请求的URL、请求的HTTP方法、请求的Header等信息,将请求路由到相应的服务实例上。通过网关,可以实现......
  • spring-websocket 简单使用
    之前自己基于netty实现了websocket协议,实现单聊以及群聊。这里记录下spring封装的spring-websocket使用方式。1.后端1.pom<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation......
  • springboot集成CAS客户端实现单点登录
    pom中引入依赖<!--cas--><dependency><groupId>org.jasig.cas.client</groupId><artifactId>cas-client-core</artifactId><version>3.6.2</version></dependen......
  • Spring MVC 教程,快速入门,深入分析
    SpringMVC教程,快速入门,深入分析资源下载:Spring_MVC_教程_快速入门_深入分析V1.1.pdfSpringMVC核心配置文件示例.rar 作者:赵磊博客:http://elf8848.iteye.com 目录一、前言二、springmvc核心类与接口三、springmvc 核心流程图四、springmvc DispatcherServlet......
  • Spring容器跳过指定对象初始化扫
    在Spring容器中,如果你希望跳过指定对象的初始化扫描,你可以使用`@ComponentScan`注解的`excludeFilters`属性来实现。`excludeFilters`属性可以指定扫描时需要排除的类或接口。例如,假设你有一个名为`MyBean`的对象,你不希望它被Spring容器初始化扫描。你可以创建一个自定义的过滤器来......
  • Spring高手之路14——深入浅出:SPI机制在JDK与Spring Boot中的应用
    1.SPI解读:什么是SPI?  SPI (ServiceProviderInterface)是一种服务发现机制,它允许第三方提供者为核心库或主框架提供实现或扩展。这种设计允许核心库/框架在不修改自身代码的情况下,通过第三方实现来增强功能。JDK原生的SPI:定义和发现:JDK的SPI主要通过在META-INF/services/目......