• Spring知识扫盲


    1、bean生命周期:看BeanFactory注释

    翻译成中文
    
    Bean工厂实现应该尽可能的支持标准的Bean生命周期接口。整套初始化方法及其标准顺序如下:
    BeanNameAware{@code setBeanName}
    BeanClassLoaderware{@code setBeanClassLoader}
    BeanFactoryAware{@code setBeanFactory}
    EnvironmentAware{@code setEnvironment}
    EmbeddedValueResolverAware{@code setEmbeddedValueResolver}
    ResourceLoaderware{@code setResourceLoader}(仅在应用程序上下文中运行时适用)
    ApplicationEventPublisherAware{@code setApplicationEventPublisher}(仅在应用程序上下文中运行时适用)
    MessageSourceAware{@code setMessageSource}(仅在应用程序上下文中运行时适用)
    ApplicationContextAware{@code setApplicationContext}(仅在应用程序上下文中运行时适用)
    ServletContextAware{@code setServletContext}(仅在web应用程序上下文中运行时适用)
    BeanPostProcessor{@code postprocessabefore initialization}方法
    初始化Bean的{@code afterPropertieSet}自定义init方法定义
    BeanPostProcessor{@code postProcessAfterInitialization}方法
    
    
    关闭Bean工厂时,以下生命周期方法适用:
    {@code postprocessabeforedisplation}销毁方法Warebean后处理器
    DisposableBean的{@code destroy}
    自定义销毁方法

     

    2、Aware接口的作用:可以理解为是个插件,如果自己创建的bean对象需要容器的内置对象,可以通过Aware接口把对象设置到这个bean里

    查看代码
    
    package beans;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    /**
     * 只要实现Aware接口,就可自动注入容器内置的某些属性,比如注入ApplicationContext、beanName
     */
    public class MyAwareBean implements ApplicationContextAware, BeanNameAware {
    
        private ApplicationContext applicationContext;
        
        private String beanName;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    
        public ApplicationContext getApplicationContext() {
            return applicationContext;
        }
    
        @Override
        public void setBeanName(String name) {
            this.beanName = name;
        }
    
        public String getBeanName() {
            return beanName;
        }
    }

    3、BeanFactoryPostProcessor与BeanPostProcessor
    BeanFactoryPostProcessor:在refresh方法的第5步执行(invokeBeanFactoryPostProcessors方法)此时已经创建好了beanFactory,并且加载好了BeanDefinition,可以在这一阶段增强(修改)BeanDefinition属性。
    BeanPostProcessor:在refresh方法的第11步执行(finishBeanFactoryInitialization方法),在这一步创建bean实例 -> 属性依赖注入 -> 初始化bean(initializeBean方法)。其中initializeBean方法包括:1、调用Aware接口方法 2、调用BeanPostProcessor.before方法 3、调用init-method方法  4、调用BeanPostProcessor.after方法  可以在这一阶段增强(修改)Bean对象属性

    查看代码
    package beans;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.stereotype.Component;
    
    /**
     * BeanFactoryPostProcessor 用于增强(修改)BeanDefinition
     * 这里把org.springframework包下所有的bean设置了Lazy
     */
    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    		String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
    		for (String beanDefinitionName : beanDefinitionNames) {
    			System.out.println(beanDefinitionName);
    			if (beanDefinitionName.startsWith("org.springframework")) {
    				continue;
    			}
    
    			BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
    			beanDefinition.setLazyInit(true);
    		}
    	}
    }
    查看代码
    package beans;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    /**
     * BeanPostProcessor用法
     *
     * 每个bean实例化之后,都会触发该方法。用于增强(修改)bean对象
     */
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		System.out.println("[BeanPostProcessor] 后置处理 " + beanName);
    		if (bean instanceof User) {
    			System.out.println(String.format("[BeanPostProcessor] 在bean初始化之后 init方法之前 beanName %s bean实例 %s 修改为 %s",
    					beanName, bean, "Before修改的值"));
    			User user = (User) bean;
    			user.setName("Before修改的值");
    		}
    
    		return bean;
    	}
    
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		if (bean instanceof User) {
    			System.out.println(String.format("[BeanPostProcessor] 在bean初始化之后 init方法之后 beanName %s bean实例 %s 修改为 %s",
    					beanName, bean, "After修改的值"));
    			User user = (User) bean;
    			user.setName("After修改的值");
    		}
    		return bean;
    	}
    
    }

     4、beanFactory与factoryBean区别?
         1)都是用来创建对象的
         2)使用beanFactory时,必须要遵循完整的创建过程,这个过程是由spring来控制的
         3)当使用factoryBean只需要调用getObject()可以返回具体的对象,对象的创建过程由自己来控制,更加灵活

    查看代码
    package beans;
    
    import org.springframework.beans.factory.FactoryBean;
    import org.springframework.stereotype.Component;
    
    /**
     * 可以自定义FactoryBean来创建bean对象,避开beanFactory的创建过程
     *
     * 获取bean
     * Object user = ctx.getBean("userFactoryBean");
     * System.out.println(user);
     * 
     * 获取FactoryBean
     * Object userFactoryBean = ctx.getBean("&userFactoryBean");
     * System.out.println(userFactoryBean);
     */
    @Component
    public class UserFactoryBean implements FactoryBean<User> {
    
        @Override
        public User getObject() throws Exception {
            return new User();
        }
    
        @Override
        public Class<?> getObjectType() {
            return User.class;
        }
    }

    5、父子容器概念

    Spring是SpringMVC父容器,SpringMVC可以获取Spring配置的bean,反之不行。

    6、循环依赖针对单例bean和原型bean会发生什么

    单例bean发生循环依赖,Spring会使用三级缓存来解决。原型bean发生循环依赖,会直接报异常。

  • 相关阅读:
    SQL中sum(),avg()等统计结果为null的解决方法
    PowerDesigner教程系列(六)概念数据模型
    只能输入正整数 已经常用的正则表达式
    PowerDesigner教程系列(四)概念数据模型
    linux全局页目录项
    开始吧
    Tomcat最大连接数问题
    CKEDITOR使用与配置
    /proc/cpuinfo 文件分析(查看CPU信息)
    Tomcat SSL配置及Tomcat CA证书安装
  • 原文地址:https://www.cnblogs.com/wwzyy/p/15857670.html
Copyright © 2020-2023  润新知