1、普通方式装配类对象  

(1)添加带有@Bean注解的方法 
User.java(带@Component注解)
 package com.demo.boot.bootenable.beanDemo1;

 import org.springframework.stereotype.Component;

 @Component
public class User {
}

User.java

(2)需要装配的类添加@Component注解

Book.java(不带@Component注解)
 package com.demo.boot.bootenable.beanDemo1;

 public class Book {
}

Book.java

==》打印

 package com.demo.boot.bootenable.beanDemo1;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean; /**
* 普通方式装配类对象
* (1)添加带有@Bean注解的方法
* (2)需要装配的类添加@Component注解
*/
@SpringBootApplication
public class BootEnableApplication { @Bean
public Book createBook(){
return new Book();
} public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(com.demo.boot.bootenable.beanDemo1.BootEnableApplication.class);
User user = context.getBean(User.class);
System.out.println(user); Book book = context.getBean(Book.class);
System.out.println(book);
context.close();
}
}

main方法

com.demo.boot.bootenable.beanDemo1.User@3301500b
com.demo.boot.bootenable.beanDemo1.Book@24b52d3e

2、使用@Import方式装配类对象

准备两个测试类User.java和Book.java

 package com.demo.boot.bootenable.beanDemo2;

 public class User {
}

User.java

 package com.demo.boot.bootenable.beanDemo2;

 public class Book {
}

Book.java

(1)方式1==》@Import({User.class,Book.class}) //直接添加需要装配的类

==》代码结构

 package com.demo.boot.bootenable.beanDemo2;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; /**
* 使用@Import方式装配类对象
*/
@SpringBootApplication
@Import({User.class,Book.class})//方式1==》直接添加需要装配的类
public class BootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context2 = SpringApplication.run(BootEnableApplication.class);
User user = context2.getBean(User.class);
System.out.println(user); Book book = context2.getBean(Book.class);
System.out.println(book);
context2.close();
}
}

Application.java

==》输出

com.demo.boot.bootenable.beanDemo2.User@24855019
com.demo.boot.bootenable.beanDemo2.Book@3abd581e

(2)方式2==》@Import(BeanImportSelector.class) //BeanImportSelector重写ImportSelector类的selectImport方法

==》代码结构

 package com.demo.boot.bootenable.beanDemo2;

 import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata; public class BeanImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{
"com.demo.boot.bootenable.beanDemo2.Book",
"com.demo.boot.bootenable.beanDemo2.User"
};
}
}

BeanImportSelector.java

 package com.demo.boot.bootenable.beanDemo2;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; /**
* 使用@Import方式装配类对象
*/
@SpringBootApplication
//@Import({User.class,Book.class})//方式1==》直接添加需要装配的类
@Import(BeanImportSelector.class)//方式2==》BeanImportSelector重写ImportSelector类的selectImport方法
public class BootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context2 = SpringApplication.run(BootEnableApplication.class);
User user = context2.getBean(User.class);
System.out.println(user); Book book = context2.getBean(Book.class);
System.out.println(book);
context2.close();
}
}

Application.java

==》输出

com.demo.boot.bootenable.beanDemo2.User@88d6f9b
com.demo.boot.bootenable.beanDemo2.Book@47d93e0d

(3)方式3==》@Import(MyBeanDefinitionRegistrar.class) //MyBeanDefinitionRegistrar重写ImportBeanDefinitionRegistrar类的registerBeanDefinitions方法

==》代码结构

 package com.demo.boot.bootenable.beanDemo3;

 import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata; /**
* ImportBeanDefinitionRegistrar可以为装配对象添加额外的属性
*/
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
BeanDefinitionBuilder userBDB = BeanDefinitionBuilder.rootBeanDefinition(User.class);
BeanDefinition userBD = userBDB.getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("user",userBD); BeanDefinitionBuilder bookBDB = BeanDefinitionBuilder.rootBeanDefinition(Book.class);
BeanDefinition bookBD = bookBDB.getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("book",bookBD);
}
}

MyBeanDefinitionRegistrar.java

 package com.demo.boot.bootenable.beanDemo3;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; /**
* 使用@Import方式装配类对象
*/
@SpringBootApplication
//@Import({User.class,Book.class})//方式1==》直接添加需要装配的类
//@Import(BeanImportSelector.class)//方式2==》BeanImportSelector重写ImportSelector类的selectImport方法
@Import(MyBeanDefinitionRegistrar.class)//方式3==》MyBeanDefinitionRegistrar重写ImportBeanDefinitionRegistrar类的registerBeanDefinitions方法
public class BootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context3 = SpringApplication.run(BootEnableApplication.class);
User user = context3.getBean("user", User.class);
System.out.println(user); Book book = context3.getBean("book", Book.class);
System.out.println(book);
context3.close();
}
}

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方法,实现类装配前打印。

 package com.demo.boot.bootenable.smple;

 import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; import java.util.ArrayList; public class MyBeanDefinitionProcessor implements BeanPostProcessor { private ArrayList<String> packages; public ArrayList<String> getPackages() {
return packages;
} public void setPackages(ArrayList<String> packages) {
this.packages = packages;
} @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { for (String pack : packages) {
if (bean.getClass().getName().startsWith(pack)) {
System.out.println("instance name:" + bean.getClass().getName());
}
}
return bean;
}
}

MyBeanDefinitionProcessor

3.2 创建类ScannerPackegeRegistar implements ImportBeanDefinitionRegistrar,重写registerBeanDefinitions方法,把自定义的MyBeanDefinitionProcessor注册进去。

 package com.demo.boot.bootenable.smple;

 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component; import java.util.Arrays;
import java.util.List; @Component
public class ScannerPackegeRegistar implements ImportBeanDefinitionRegistrar {
/**
* 注册实体对象被装配前回调方法
* @param annotationMetadata
* @param beanDefinitionRegistry
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
String[] strArr = (String[]) annotationMetadata
.getAnnotationAttributes(EnableScanner.class.getName())
.get("packages"); List<String> packages = Arrays.asList(strArr);
System.out.println(packages);
BeanDefinitionBuilder dbd = BeanDefinitionBuilder.rootBeanDefinition(MyBeanDefinitionProcessor.class);
dbd.addPropertyValue("packages", packages); beanDefinitionRegistry.registerBeanDefinition(MyBeanDefinitionProcessor.class.getName(), dbd.getBeanDefinition());
} }

ScannerPackegeRegistar.java

3.3 自定义注解EnableScanner

 package com.demo.boot.bootenable.smple;

 import org.springframework.context.annotation.Import;
import java.lang.annotation.*; @Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ScannerPackegeRegistar.class)
public @interface EnableScanner {
String[] packages();
}

EnableScanner.java

3.4 创建Person.java、Student.java和UserVO.java类

 package com.demo.boot.bootenable.smple.bean;

 import org.springframework.stereotype.Component;

 @Component
public class Person {
}

Person.java

 package com.demo.boot.bootenable.smple.bean;

 import org.springframework.stereotype.Component;

 @Component
public class Student {
}

Student.java

 package com.demo.boot.bootenable.smple.vo;

 import org.springframework.stereotype.Component;

 @Component
public class UserVO {
}

UserVO.java

3.5 Application

 package com.demo.boot.bootenable.smple;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication
@EnableScanner(packages = {"com.demo.boot.bootenable.smple.bean", "com.demo.boot.bootenable.smple.vo"})//启用监控扫描类的注解
public class ScannerPackegeApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(ScannerPackegeApplication.class, args); context.close();
}
}

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初始化前装配的类。

最新文章

  1. 安装 Visual Studio Web Tools 的奇怪问题
  2. mybatis动态切换数据源
  3. JavaScript + SVG实现Web前端WorkFlow工作流DAG有向无环图
  4. Jquery网页加载进度条(随笔,当然要随便写,当日记动态心情写咯)
  5. action中result没有值
  6. Odoo Entypo Regular Icon List
  7. codeforce 603B - Moodular Arithmetic
  8. 同步窗体移动 FormMove
  9. const和violate
  10. JQuery 图片延迟加载并等比缩放插件
  11. 学习MVC遇到的问题
  12. PyMOTW: heapq¶
  13. C# 读取IE缓存文件(2)
  14. SQL server 行转列 列转行
  15. java byte 梳理
  16. oracle 优化方法总结
  17. EF Core
  18. Less入门与安装(转)
  19. js定位当前位置的坐标经纬度和地点名称和天气
  20. 对va_list; va_start ; va_end ;vsprintf理解(转)

热门文章

  1. 基于DRF的图书增删改查
  2. Linux_NetworkManager_RHEL7
  3. Jmeter测试HTTP接口
  4. 2018.03.27 python pandas merge join 使用
  5. java通过jna调用so
  6. 【Qt开发】Qt中图像的显示与基本操作
  7. python可视化:matplotlib系列
  8. [Python3] 003 变量类型概述 &amp; 数字类型详叙
  9. vps国外节点ubuntu修改时区重启不失效
  10. 教你在 IntelliJ IDEA 中使用 VIM!