Spring Bean的生命周期函数
  R07BuTtplK4h 2024年08月07日 60 0

🍓Bean的生命周期

  1. 📌Bean定义
  2. 📌Bean注册
  3. 📌Bean初始化
  4. 📌Bean销毁

🍓Bean注册

?>Bean定义时会调用BeanDefinitionRegistryPostProcessor的子类的两个实现方法postProcessBeanDefinitionRegistrypostProcessBeanFactory

  1. 📌postProcessBeanDefinitionRegistry,可以注册Bean(先调)

  2. 📌postProcessBeanFactory,可以获取到BeanFactory,BeanFactory能做的这个方法都能做(后调)

    点击查看代码
    import cn.com.xuhx.service.impl.UserServiceImpl;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.beans.factory.support.RootBeanDefinition;
    import org.springframework.stereotype.Component;
    
    /**
     * 作用:动态注册BeanDefinition
     * 调动时机:IOC加载注册BeanDefinition 的时候会调用
     */
    @Component
    public class MyBeanDefinitionRegistyPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
    	/**
    	 * 动态注册Bean
    	 * 先执行
    	 * @param beanDefinitionRegistry the bean definition registry used by the application context
    	 * @throws BeansException
    	 */
    	@Override
    	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
    		RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(UserServiceImpl.class);
    		//手动注册UserServiceImpl的Bean
    		beanDefinitionRegistry.registerBeanDefinition("userService", rootBeanDefinition);
    	}
    
    	/**
    	 * configurableListableBeanFactory Bean工厂,Bean工厂一切能做的,都能在这里做
    	 *  可以注册Bean
    	 *  可以修改BeanDefinition的定义 例如单例变多例
    	 *  可以通过Bean的名称获取Bean
    	 *  可以销毁Bean
    	 * 后执行
    	 * @param configurableListableBeanFactory the bean factory used by the application context
    	 * @throws BeansException
    	 */
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    
    	}
    }
    
    

🍓Bean初始化

🍒🍒Aware接口

🍎🍎🍎BeanNameAware

?>通过实现BeanNameAware接口,重写setBeanName方法可以获得当前类的BeanName

点击查看代码
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService, BeanNameAware {

    /**
     * UserServiceImpl的BeanName
     */
    private String beanName;

    /**
     * 通过实现BeanNameAware重写setBeanName方法获取当前对象的BeanName
     * @param name the name of the bean in the factory.
     */
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }

    public String getBeanName() {
        return beanName;
    }
}

🍎🍎🍎BeanFactoryAware

?>通过实现BeanFactoryAware接口,重写setBeanFactory方法可以获取BeanFactory,可以用于注册Bean、修改BeanDefinition定义、根据BeanName获取Bean,销毁Bean等。

点击查看代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService, BeanFactoryAware {

    /**
     * Bean工厂
     */
    private BeanFactory beanFactory;

    /**
     * BeanFactoryAware重写的方法,可以获取BeanFactory
     * @param beanFactory owning BeanFactory (never {@code null}).
     * @throws BeansException
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }
}

🍎🍎🍎BeanClassLoaderAware

?>通过实现BeanClassLoaderAware接口,重写setBeanClassLoader方法可以获取类加载器,用于动态加载类

点击查看代码
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService, BeanClassLoaderAware {

    /**
     * 类加载器
     */
    private ClassLoader classLoader;

    /**
     * BeanClassLoaderAware重写的方法,可以获取类加载器
     * @param classLoader the owning class loader
     */
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    public ClassLoader getClassLoader() {
        return classLoader;
    }
}

🍎🍎🍎EnvironmentAware

?>通过实现EnvironmentAware接口,重写setEnvironment方法可以获取Environment对象,用于读取配置文件

点击查看代码
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService, EnvironmentAware {

    /**
     * 环境管理对象
     */
    private Environment env;

    /**
     * EnvironmentAware重写的方法,可以获取Environment
     * @param environment
     */
    @Override
    public void setEnvironment(Environment environment) {
        this.env = environment;
    }

    public Environment getEnv() {
        return env;
    }
}

🍎🍎🍎EmbeddedValueResolverAware

?>通过实现EmbeddedValueResolverAware接口,重写setEmbeddedValueResolver方法获取StringValueResolver对象,用于解析字符串

点击查看代码
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Service;
import org.springframework.util.StringValueResolver;

@Service
public class UserServiceImpl implements UserService, EmbeddedValueResolverAware {

    /**
     * 字符串占位符解析对象
     */
    private StringValueResolver resolver;

    /**
     * EmbeddedValueResolverAware重写的方法,可以获取StringValueResolver
     * @param resolver
     */
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.resolver = resolver;
    }

    public StringValueResolver getResolver() {
        return resolver;
    }

    @Override
    public String getMessage() {
        String message = "你好,${student.name}";
        return resolver.resolveStringValue(message);
    }
}

!>properties配置文件的中文需要转码(与编码格式无关),否则会乱码,可以使用jdk8自带的程序native2ascii.exe编码

🍎🍎🍎ResourceLoaderAware

?>通过实现ResourceLoaderAware接口,重写setResourceLoader方法获取ResourceLoader对象,用于加载配置文件

点击查看代码
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import java.io.*;

@Service
public class UserServiceImpl implements UserService, ResourceLoaderAware {

    /**
     * resourceLoader对象
     */
    private ResourceLoader resourceLoader;

    @javax.annotation.Resource
    private ResourceUtils resourceUtils;

    /**
     * ResourceLoaderAware重写的方法,可以获取resourceLoader
     * @param resourceLoader
     */
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public String readFile() throws IOException {
        Resource resource = resourceLoader.getResource("classpath:/abc");
        return resourceUtils.getContent(resource);
    }
}

🍎🍎🍎ApplicationEventPublisherAware

?>通过实现ApplicationEventPublisherAware接口,重写setApplicationEventPublisher方法获取ApplicationEventPublisher对象,用于订阅发布事件。

事件对象
import org.springframework.context.ApplicationEvent;

/**
 * 用户事件
 */
public class UserEvent extends ApplicationEvent {

    private String message;

    private String topic;

     public UserEvent(Object source, String message, String topic) {
        super(source);
        this.message = message;
        this.topic = topic;
    }

    public String getMessage() {
        return message;
    }

    public String getTopic() {
        return topic;
    }
}
事件监听器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * 用户事件监听器
 */
@Component
public class UserEventListener {

    /**
     * 日志对象
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 监听器
     * @param userEvent
     */
    @EventListener(condition = "'heiBei'.equals(#userEvent.topic)")
    @Async
    public void receiveHeiBeiUser(UserEvent userEvent) {
        logger.info("receive heiBei: " + userEvent.getTopic() + ":" + userEvent.getMessage());
    }

    /**
     * 监听器
     * @param userEvent
     */
    @EventListener(condition = "'jiangSu'.equals(#userEvent.topic)")
    @Async
    public void receiveJiangSuUser(UserEvent userEvent) {
        logger.info("receive JiangSu: " + userEvent.getTopic() + ":" + userEvent.getMessage());
    }
}
发送消息
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

/**
 * 消息发布
 */
@Service
public class UserServiceImpl implements UserService, ApplicationEventPublisherAware {

    /**
     * 消息发布对象
     */
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * ApplicationEventPublisherAware重写的方法,可以获取applicationEventPublisher
     * @param applicationEventPublisher
     */
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    /**
     * 发送消息
     */
    public void publishEvent(String topic) {
        UserEvent userTopic = new UserEvent(this, "Hello World!", topic);
        applicationEventPublisher.publishEvent(userTopic);
    }
}

🍎🍎🍎MessageSourceAware

?>通过实现MessageSourceAware接口,重写setMessageSource方法获取MessageSource对象,用于实现国际化功能

创建用户事件
import org.springframework.context.ApplicationEvent;

/**
 * 用户事件
 */
public class UserEvent extends ApplicationEvent {

    private String message;

    private String topic;

     public UserEvent(Object source, String message, String topic) {
        super(source);
        this.message = message;
        this.topic = topic;
    }

    public String getMessage() {
        return message;
    }

    public String getTopic() {
        return topic;
    }
}
用户事件监听器
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * 用户事件监听器
 */
@Component
public class UserEventListener {

    /**
     * 日志对象
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 监听器(异步需要在启动器上加@EnableAsync)
     * @param userEvent
     */
    @EventListener(condition = "'heiBei'.equals(#userEvent.topic)")
    @Async
    public void receiveHeiBeiUser(UserEvent userEvent) {
        logger.info("receive heiBei: " + userEvent.getTopic() + ":" + userEvent.getMessage());
    }

    /**
     * 监听器
     * @param userEvent
     */
    @EventListener(condition = "'jiangSu'.equals(#userEvent.topic)")
    @Async
    public void receiveJiangSuUser(UserEvent userEvent) {
        logger.info("receive JiangSu: " + userEvent.getTopic() + ":" + userEvent.getMessage());
    }
}
发送消息
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.stereotype.Service;
import java.util.Locale;

/**
 * 消息发布
 */
@Service
public class UserServiceImpl implements UserService, MessageSourceAware {

    private MessageSource messageSource;

    /**
     * MessageSourceAware重写的方法,可以获取messageSource
     * @param messageSource
     */
    @Override
    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    public String getMessage(String lanuageType) {
        if ("US".equalsIgnoreCase(lanuageType)) {
            return messageSource.getMessage("message", null, new Locale("en", "US"));
        } else if ("CN".equalsIgnoreCase(lanuageType)) {
            return messageSource.getMessage("message", null, new Locale("zh", "CN"));
        }
        return messageSource.getMessage("message", null, null);
    }
}

创建Message配置文件
image
添加配置
spring.messages.basename=i18n/Message

!>properties配置文件的中文需要转码(与编码格式无关),否则会乱码,可以使用jdk8自带的程序native2ascii.exe编码

🍎🍎🍎ImportAware

?>通过实现ImportAware接口,重写setImportMetadata方法获取AnnotationMetadata对象,用于获取注解信息

点击查看代码
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Service;


@Service
public class UserServiceImpl implements UserService, ImportAware {

    /**
     * 获取注解信息
     */
    private AnnotationMetadata annotationMetadata;

    /**
     * ImportAware重写的方法,可以获取AnnotationMetadata
     * @param importMetadata
     */
    @Override
    public void setImportMetadata(AnnotationMetadata importMetadata) {
        annotationMetadata = importMetadata;
    }
}

🍒🍒@PostConstruct

?>当Spring IOC Bean初始化时会调用@PostConstruct标注的方法

点击查看代码
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;


@Service
public class UserServiceImpl implements UserService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 初始化
     */
    @PostConstruct
    public void init() {
        logger.info("UserServiceImpl初始化");
    }
}

🍓Bean生命周期的回调

🍒🍒BeanPostProcessor

?>Bean初始化前会调用BeanPostProcessor的postProcessBeforeInitialization方法,Bean初始化后会调用方法postProcessAfterInitialization

点击查看代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * Bean初始化前
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        logger.info("postProcessBeforeInitialization Bean = {}, BeanName = {}", bean, beanName);
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    /**
     * Bean初始化后
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        logger.info("postProcessAfterInitialization Bean = {}, BeanName = {}", bean, beanName);
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

🍒🍒InitializingBean

?>Bean初始化会调用InitializingBean的实现方法afterPropertiesSet,作用相当于@PostConstruct

点击查看代码
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService, InitializingBean {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("UserServiceImpl初始化");
    }
}

🍒🍒init-method

?>Bean初始化会调用init-method指定的方法,作用相当于InitializingBean.afterPropertiesSet@PostConstruct

点击查看代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanConfiguration {

    @Bean(name = "userService", initMethod = "init")
    public UserService getUserService() {
        return new UserServiceImpl();
    }
}

🍒🍒DisposableBean

?>Bean销毁会调用DisposableBean的实现方法destroy

点击查看代码
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService, DisposableBean {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void destroy() throws Exception {
        logger.info("UserServiceImpl被销毁了");
    }
}

🍒🍒destroy-method

?>Bean销毁会调用destroy-method指定的方法,作用相当于DisposableBean.destroy

点击查看代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanConfiguration {

    @Bean(name = "userService", destroyMethod = "destroy")
    public UserService getUserService() {
        return new UserServiceImpl();
    }
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年08月07日 0

暂无评论

推荐阅读
  VGxawBTN4xmE   2天前   18   0   0 Java
  FHUfYd9S4EP5   4天前   28   0   0 Java
  u8s65Xl4dX8N   4小时前   9   0   0 Java
  qCe06rFCa8NK   4小时前   13   0   0 Java
  ZTo294hNoDcA   4天前   28   0   0 Java
  FHUfYd9S4EP5   4天前   23   0   0 Java