Spring常用技術拡張点

28274 ワード

SpringBeanのライフサイクル
  • 容器起動後、scopeをsingletonとして怠惰でない負荷のBeanを実例化し、Bean定義に従って情報を配置し、すべての属性
  • ビーンがビーンNameAwareインターフェースを実現したら、このインターフェースのset BenName()方法
  • ビーンFactoryAwareインターフェースを実現したら、このインターフェースのsetBenFactory()方法
  • ビーンがAppplication ContactAwareインターフェースを実現したら、そのインターフェースのsetApple Controtext()方法
  • ビーンPostProcessorインターフェースが実現されれば、このインターフェースのpostProcess BeforeInitialzation()方法
  • ビーンがInitializingBeanインターフェースを実現すると、このインターフェースのafterPropertiesset()方法
  • ビーンがinit-method方法を配置すると、init-method配置の方法
  • ビーンがビーンPostProcessorインターフェースを実現すれば、このインターフェースのpostProcess After Initialization()方法
  • scopeがsingletonであるBeanに対して、SpringのIOC容器にはこのBenの例がキャッシュされている。scopeがprototypeであるBeanに対しては、呼び出しのたびにnewの新たな対象となり、そのライフサイクルは呼び出し元管理
  • 容器が閉じた後、ビーンがDispable Beanインターフェースを実現すれば、当該インターフェースのdestroy()方法をフィードバックする
  • ビーンがdestroy-method方法を配置すると、destroy-method配置の方法
  • 一般的な拡張子
    @Component
    public class CustomInitialize extends CommonLoggerDefine
    		implements ApplicationContextAware, InitializingBean, DisposableBean, InstantiationAwareBeanPostProcessor,
    		BeanNameAware, BeanFactoryAware, BeanFactoryPostProcessor, BeanPostProcessor {
    
    	@Override
    	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    		logger.info("===Custom ApplicationContext===");
    	}
    
    	@Override
    	public void afterPropertiesSet() throws Exception {
    		logger.info("===Custom InitializingBean===");
    	}
    
    	@Override
    	public void destroy() throws Exception {
    		logger.info("===Custom DisposableBean===");
    	}
    
    	@Override
    	public void setBeanFactory(BeanFactory paramBeanFactory) throws BeansException {
    		logger.info("===Custom BeanFactoryAware===");
    	}
    
    	@Override
    	public void setBeanName(String paramString) {
    		logger.info("===Custom BeanNameAware===");
    	}
    
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory paramConfigurableListableBeanFactory)
    			throws BeansException {
    		BeanDefinition bd = paramConfigurableListableBeanFactory.getBeanDefinition("userBean");
    		MutablePropertyValues pv = bd.getPropertyValues();
    		bd.setScope("singleton");
    		logger.info("===Custom BeanFactoryPostProcessor===" + pv.getPropertyValues());
    	}
    
    	@Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		logger.info("===Custom BeanPostProcessor Before===");
    		return bean;
    	}
    
    	@Override
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		logger.info("===Custom BeanPostProcessor After===");
    		return bean;
    	}
    
    	@Override
    	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    		logger.info("===Custom InstantiationAwareBeanPostProcessor Before===");
    		return null;
    	}
    
    	@Override
    	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    		logger.info("===Custom InstantiationAwareBeanPostProcessor After===");
    		return true;
    	}
    
    	@Override
    	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
    			throws BeansException {
    		logger.info("===Custom InstantiationAwareBeanPostProcessor postProcessProperties===");
    		return null;
    	}
    
    	@Override
    	public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
    			String beanName) throws BeansException {
    		logger.info("===Custom InstantiationAwareBeanPostProcessor postProcessPropertyValues===");
    		return pvs;
    	}
    }
    
    public class UserBean extends CommonLoggerDefine {
    
    	@PostConstruct
    	public void postConstruct() {
    		logger.info("===Custom PostConstruct===");
    	}
    	
    	@PreDestroy
    	public void preDestroy() {
    		logger.info("===Custom PreDestroy===");
    	}
    }
    
    public class CustomBean extends CommonLoggerDefine {
    
    	public void start() {
    		logger.info("===Custom CustomBean Starter===");
    	}
    
    	public void destroy() {
    		logger.info("===Custom CustomBean Destroy===");
    	}
    }
    
    /**
     *          Bean,          ,      &  :@Resource(name = "&customFactoryBean")
     * 
     * @author LEric
     */
    public class CustomFactoryBean extends CommonLoggerDefine implements FactoryBean<UserBean> {
    
    	@Override
    	public UserBean getObject() throws Exception {
    		logger.info("===Custom FactoryBean Object===");
    		return new UserBean();
    	}
    
    	@Override
    	public Class<?> getObjectType() {
    		logger.info("===Custom FactoryBean Class===");
    		return UserBean.class;
    	}
    }
    
    public class CommonLoggerDefine {
    
    	public Logger logger = LoggerFactory.getLogger(getClass());
    }
    
    クラスを開始
    @SpringBootApplication(scanBasePackages = "com.xpt.extension.advance")
    public class AdvanceApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(AdvanceApplication.class, args);
    		System.exit(0);
    	}
    
    	@Bean(initMethod = "start", destroyMethod = "destroy")
    	public CustomBean customBean() {
    		return new CustomBean();
    	}
    
    	@Bean(name = "customFactoryBean")
    	public CustomFactoryBean toolFactory() {
    		return new CustomFactoryBean();
    	}
    
    	@Bean(name = "userBean")
    	public UserBean userBean() {
    		return new UserBean();
    	}
    }
    
    コメント
    カスタムSpring-Boot-Starterによるカスタムラベル解析の実現
    /**
     *     XML        
     * 
     * @author LEric
     */
    public class CustomHandler extends NamespaceHandlerSupport {
    
    	@Override
    	public void init() {
    		registerBeanDefinitionParser("label", new BeanParser());
    	}
    }
    
    /**
     *     AbstractSingleBeanDefinitionParser    BeanDefinitionParser      
     * 
     * @author LEric
     *
     */
    public class BeanParser implements BeanDefinitionParser {
    
    	@Override
    	public BeanDefinition parse(Element element, ParserContext parserContext) {
    		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
    		return builder.getBeanDefinition();
    	}
    }
    
    /**
     *    Spring-Boot-Starter       , @Import      
     * 
     * @author LEric
     *
     */
    public class CustomImport implements ImportBeanDefinitionRegistrar {
    
    	@Override
    	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    		//        
    	}
    }
    
    締め括りをつける
    Springでよく使われている技術の拡張点はAbstractAplicationComptextのrefresh()の方法で見つけられます。BeanDefinition:Beanの情報を記述します。例えば、class情報、属性情報、単例かどうか、遅延荷重などです。一般的なインターフェースはありますか?
  • FactoryBen、AOPのベースバー
  • ビーンPostProcessor、各bean初期化前後の操作
  • InstantiationAwareBenPostProcessorでは、ビーン毎の実用化前後の操作
  • ビーンNameAwareは、現在のBeanのId
  • Application ControtextAware、コンテキストを取得する
  • ビーンファクトリーAware、ビーン工場に対する処理
  • ビーンFactoryPostProcessorは、ビーンが作成する前にビーンのメタ属性を読み取り、メタ属性を修正し、例えばビーンのscope属性をsingletonからprototype
  • InitializingBeanは、属性設定完了後の操作
  • Displable Bean、容器を閉じる前の操作
  • コメント
  • BenPostProcessor:各Beanは初期化前後にその方法をリピートします。例えば、init-method、InitializingBenなど
  • InitializingBeanの使用は推奨されていません。Springとの結合が緊密すぎるので、@PostCostruct注釈
  • Spring容器の最も一般的な2つの拡張点:BenFactoryPostProcessorとBenPostProcessorの対応方法はSpringによって容器初期化中に呼び出され、この時には全てのBenの定義情報は初期化されていますが、これらのBenはまだ実用化されていません。
  • postProcess Before Initialization:Bean毎の実装後、初期化前に呼び出される
  • postProcess After Initialization:beanごとに初期化されて呼び出される
  • Application Contectは、Appplication Contact AwareProcessorを利用してAppplication Controseの中で特有のいくつかのAwareの呼び出しを完了し、発生するタイミングはBen初期化前:(6.1)Eviroment Aware:コンテキストにEviromentを注入し、配置属性を取得する場合に使用する(6.2)EmbodValueResloverAware:コンテキストでEmbodValueResolaverを注入し、パラメータ解析(6.3)Resource Loader Aware:コンテキストを設定する(6.4)Aplication Event Publisher Aware:Aplication Event Publisherインターフェースを実現し、自分自身を注入する(6.5 Meurce Aware)。Application ContactextAware:自己注入
  • BeanClass Loader Aware:現在のBeanをロードするClass Loaderを注入します。