javascript
SpringBoot框架(4)-- 类装配及Bean装配监听器
1、普通方式裝配類對象??
(1)添加帶有@Bean注解的方法? User.java(帶@Component注解) 1 package com.demo.boot.bootenable.beanDemo1; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class User { 7 } User.java?
(2)需要裝配的類添加@Component注解
==》打印
1 package com.demo.boot.bootenable.beanDemo1; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.context.ConfigurableApplicationContext; 6 import org.springframework.context.annotation.Bean; 7 8 /** 9 * 普通方式裝配類對象 10 * (1)添加帶有@Bean注解的方法 11 * (2)需要裝配的類添加@Component注解 12 */ 13 @SpringBootApplication 14 public class BootEnableApplication { 15 16 @Bean 17 public Book createBook(){ 18 return new Book(); 19 } 20 21 public static void main(String[] args) { 22 ConfigurableApplicationContext context = SpringApplication.run(com.demo.boot.bootenable.beanDemo1.BootEnableApplication.class); 23 User user = context.getBean(User.class); 24 System.out.println(user); 25 26 Book book = context.getBean(Book.class); 27 System.out.println(book); 28 context.close(); 29 } 30 } main方法com.demo.boot.bootenable.beanDemo1.User@3301500b
com.demo.boot.bootenable.beanDemo1.Book@24b52d3e
?
2、使用@Import方式裝配類對象
準備兩個測試類User.java和Book.java
1 package com.demo.boot.bootenable.beanDemo2; 2 3 public class User { 4 } User.java 1 package com.demo.boot.bootenable.beanDemo2; 2 3 public class Book { 4 } Book.java(1)方式1==》@Import({User.class,Book.class}) //直接添加需要裝配的類
? ? ? ? ==》代碼結構
? ? ? ??
1 package com.demo.boot.bootenable.beanDemo2; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.context.ConfigurableApplicationContext; 6 import org.springframework.context.annotation.Import; 7 8 /** 9 * 使用@Import方式裝配類對象 10 */ 11 @SpringBootApplication 12 @Import({User.class,Book.class})//方式1==》直接添加需要裝配的類 13 public class BootEnableApplication { 14 public static void main(String[] args) { 15 ConfigurableApplicationContext context2 = SpringApplication.run(BootEnableApplication.class); 16 User user = context2.getBean(User.class); 17 System.out.println(user); 18 19 Book book = context2.getBean(Book.class); 20 System.out.println(book); 21 context2.close(); 22 } 23 } Application.java? ? ? ? ==》輸出
com.demo.boot.bootenable.beanDemo2.User@24855019
com.demo.boot.bootenable.beanDemo2.Book@3abd581e
(2)方式2==》@Import(BeanImportSelector.class) //BeanImportSelector重寫ImportSelector類的selectImport方法
? ? ? ? ==》代碼結構
? ? ? ? ?
1 package com.demo.boot.bootenable.beanDemo2; 2 3 import org.springframework.context.annotation.ImportSelector; 4 import org.springframework.core.type.AnnotationMetadata; 5 6 public class BeanImportSelector implements ImportSelector { 7 @Override 8 public String[] selectImports(AnnotationMetadata annotationMetadata) { 9 return new String[]{ 10 "com.demo.boot.bootenable.beanDemo2.Book", 11 "com.demo.boot.bootenable.beanDemo2.User" 12 }; 13 } 14 } BeanImportSelector.java 1 package com.demo.boot.bootenable.beanDemo2; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.context.ConfigurableApplicationContext; 6 import org.springframework.context.annotation.Import; 7 8 /** 9 * 使用@Import方式裝配類對象 10 */ 11 @SpringBootApplication 12 //@Import({User.class,Book.class})//方式1==》直接添加需要裝配的類 13 @Import(BeanImportSelector.class)//方式2==》BeanImportSelector重寫ImportSelector類的selectImport方法 14 public class BootEnableApplication { 15 public static void main(String[] args) { 16 ConfigurableApplicationContext context2 = SpringApplication.run(BootEnableApplication.class); 17 User user = context2.getBean(User.class); 18 System.out.println(user); 19 20 Book book = context2.getBean(Book.class); 21 System.out.println(book); 22 context2.close(); 23 } 24 } Application.java? ? ? ? ==》輸出
com.demo.boot.bootenable.beanDemo2.User@88d6f9b
com.demo.boot.bootenable.beanDemo2.Book@47d93e0d
(3)方式3==》@Import(MyBeanDefinitionRegistrar.class) //MyBeanDefinitionRegistrar重寫ImportBeanDefinitionRegistrar類的registerBeanDefinitions方法
? ? ? ? ?==》代碼結構
? ? ? ? ?
1 package com.demo.boot.bootenable.beanDemo3; 2 3 import org.springframework.beans.factory.config.BeanDefinition; 4 import org.springframework.beans.factory.support.BeanDefinitionBuilder; 5 import org.springframework.beans.factory.support.BeanDefinitionRegistry; 6 import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; 7 import org.springframework.core.type.AnnotationMetadata; 8 9 /** 10 * ImportBeanDefinitionRegistrar可以為裝配對象添加額外的屬性 11 */ 12 public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { 13 @Override 14 public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { 15 BeanDefinitionBuilder userBDB = BeanDefinitionBuilder.rootBeanDefinition(User.class); 16 BeanDefinition userBD = userBDB.getBeanDefinition(); 17 beanDefinitionRegistry.registerBeanDefinition("user",userBD); 18 19 BeanDefinitionBuilder bookBDB = BeanDefinitionBuilder.rootBeanDefinition(Book.class); 20 BeanDefinition bookBD = bookBDB.getBeanDefinition(); 21 beanDefinitionRegistry.registerBeanDefinition("book",bookBD); 22 } 23 } MyBeanDefinitionRegistrar.java 1 package com.demo.boot.bootenable.beanDemo3; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.context.ConfigurableApplicationContext; 6 import org.springframework.context.annotation.Import; 7 8 /** 9 * 使用@Import方式裝配類對象 10 */ 11 @SpringBootApplication 12 //@Import({User.class,Book.class})//方式1==》直接添加需要裝配的類 13 //@Import(BeanImportSelector.class)//方式2==》BeanImportSelector重寫ImportSelector類的selectImport方法 14 @Import(MyBeanDefinitionRegistrar.class)//方式3==》MyBeanDefinitionRegistrar重寫ImportBeanDefinitionRegistrar類的registerBeanDefinitions方法 15 public class BootEnableApplication { 16 public static void main(String[] args) { 17 ConfigurableApplicationContext context3 = SpringApplication.run(BootEnableApplication.class); 18 User user = context3.getBean("user", User.class); 19 System.out.println(user); 20 21 Book book = context3.getBean("book", Book.class); 22 System.out.println(book); 23 context3.close(); 24 } 25 } Application.java? ? ? ? ==》輸出
com.demo.boot.bootenable.beanDemo3.User@4d0402b
com.demo.boot.bootenable.beanDemo3.Book@2fa7ae9
備注:以上demo中,都是指定需要裝配的類,不指定則不會自動自動裝配
?
3、Bean裝配監聽器
? bean在裝配過程中會執行一系列方法,其中有postProcessBeforeInitialization --> afterPropertiesSet --> init-method -- > postProcessAfterInitialization。
? (1)postProcessBeforeInitialization方法,在bean初始化之前執行
? (2)afterPropertiesSet方法,初始化bean的時候執行
? (3)nit-method方法,初始化bean的時候執行
? (4)postProcessAfterInitialization方法,在bean初始化之后執行。
? 因此,我們可以在裝配時,進行攔截處理。這里demo選用重寫postProcessBeforeInitialization方法
? ? 代碼結構
? ??
3.1 創建類?MyBeanDefinitionProcessor繼承BeanPostProcessor,添加屬性packages的構造器,并重寫postProcessBeforeInitialization方法,實現類裝配前打印。
1 package com.demo.boot.bootenable.smple; 2 3 import org.springframework.beans.BeansException; 4 import org.springframework.beans.factory.config.BeanPostProcessor; 5 6 import java.util.ArrayList; 7 8 public class MyBeanDefinitionProcessor implements BeanPostProcessor { 9 10 private ArrayList<String> packages; 11 12 public ArrayList<String> getPackages() { 13 return packages; 14 } 15 16 public void setPackages(ArrayList<String> packages) { 17 this.packages = packages; 18 } 19 20 @Override 21 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 22 23 for (String pack : packages) { 24 if (bean.getClass().getName().startsWith(pack)) { 25 System.out.println("instance name:" + bean.getClass().getName()); 26 } 27 } 28 return bean; 29 } 30 } MyBeanDefinitionProcessor?
3.2 創建類ScannerPackegeRegistar implements ImportBeanDefinitionRegistrar,重寫registerBeanDefinitions方法,把自定義的MyBeanDefinitionProcessor注冊進去。
1 package com.demo.boot.bootenable.smple; 2 3 import org.springframework.beans.factory.support.BeanDefinitionBuilder; 4 import org.springframework.beans.factory.support.BeanDefinitionRegistry; 5 import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; 6 import org.springframework.core.type.AnnotationMetadata; 7 import org.springframework.stereotype.Component; 8 9 import java.util.Arrays; 10 import java.util.List; 11 12 @Component 13 public class ScannerPackegeRegistar implements ImportBeanDefinitionRegistrar { 14 /** 15 * 注冊實體對象被裝配前回調方法 16 * @param annotationMetadata 17 * @param beanDefinitionRegistry 18 */ 19 @Override 20 public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { 21 String[] strArr = (String[]) annotationMetadata 22 .getAnnotationAttributes(EnableScanner.class.getName()) 23 .get("packages"); 24 25 List<String> packages = Arrays.asList(strArr); 26 System.out.println(packages); 27 BeanDefinitionBuilder dbd = BeanDefinitionBuilder.rootBeanDefinition(MyBeanDefinitionProcessor.class); 28 dbd.addPropertyValue("packages", packages); 29 30 beanDefinitionRegistry.registerBeanDefinition(MyBeanDefinitionProcessor.class.getName(), dbd.getBeanDefinition()); 31 } 32 33 } ScannerPackegeRegistar.java?
3.3 自定義注解EnableScanner
1 package com.demo.boot.bootenable.smple; 2 3 import org.springframework.context.annotation.Import; 4 import java.lang.annotation.*; 5 6 @Target({ElementType.TYPE}) 7 @Retention(RetentionPolicy.RUNTIME) 8 @Documented 9 @Import(ScannerPackegeRegistar.class) 10 public @interface EnableScanner { 11 String[] packages(); 12 } EnableScanner.java?
3.4 創建Person.java、Student.java和UserVO.java類
1 package com.demo.boot.bootenable.smple.bean; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class Person { 7 } Person.java 1 package com.demo.boot.bootenable.smple.bean; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class Student { 7 } Student.java 1 package com.demo.boot.bootenable.smple.vo; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class UserVO { 7 } UserVO.java?
3.5 Application
1 package com.demo.boot.bootenable.smple; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.context.ConfigurableApplicationContext; 6 7 @SpringBootApplication 8 @EnableScanner(packages = {"com.demo.boot.bootenable.smple.bean", "com.demo.boot.bootenable.smple.vo"})//啟用監控掃描類的注解 9 public class ScannerPackegeApplication { 10 public static void main(String[] args) { 11 ConfigurableApplicationContext context = SpringApplication.run(ScannerPackegeApplication.class, args); 12 13 context.close(); 14 } 15 } Application.java輸出結果
instance name:com.demo.boot.bootenable.smple.bean.Person
instance name:com.demo.boot.bootenable.smple.bean.Student
instance name:com.demo.boot.bootenable.smple.vo.UserVO
?
總結思路
1、把類裝配到SpringBoot容器管理主要分兩大類
? ? (1)普通方式:直接在類上加@Component注解,或者在創建對象方法加上@Bean注解
? ? (2)通過@Import注解:直接指定需要裝配的類,傳入
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 重寫ImportSelector類的selectImport方法的類,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?或重寫ImportBeanDefinitionRegistrar類的registerBeanDefinitions方法
2、Bean裝配監聽器
? (1)定義注解,接受需要裝配類的包名
? (2)創建ImportBeanDefinitionRegistrar的子類ScannerPackegeRegistar,重寫registerBeanDefinitions方法,作用是把監聽器注冊到SpringBoot初始化Bean的過程中。
? (3)創建BeanPostProcessor的子類MyBeanDefinitionProcessor,重寫postProcessBeforeInitialization方法,作用是監聽在bean初始化前裝配的類。
轉載于:https://www.cnblogs.com/lfhappy/p/10939015.html
總結
以上是生活随笔為你收集整理的SpringBoot框架(4)-- 类装配及Bean装配监听器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MAC97A6检测
- 下一篇: fastjson将json字符串转为Ma