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

SpringBoot框架(4)-- 类装配及Bean装配监听器的更多相关文章

  1. Bean 装配,从 Spring 到 Spring Boot

    目录  从SSM的集成谈到Bean的装配  Bean的装配 由XML到Java Config 自动扫描 Bean的注入 SSM集成的Java版 Spring Boot Magic Auto Confi ...

  2. Spring对Bean装配详解

    1.Spring提供了三种装配bean的方式: 2.自动装配bean: 3.通过Java代码装配bean 4.通过XML装配bean 前言:创建对象的协作关系称为装配,也就是DI(依赖注入)的本质.而 ...

  3. SpringBoot框架(3)--条件装配

    场景:需要根据系统的编码格式有选择装配类. 分析:最直接的实现方式,定义各种编码格式对应的处理类,可以通过System.getProperty("file.encoding")获得 ...

  4. 使用spring框架,用xml方式进行bean装配出现“The fully qualified name of the bean's class, except if it serves...”

    使用spring框架,用xml方式进行bean装配出现“The fully qualified name of the bean's class, except if it serves...”. 原 ...

  5. SpringBoot:认认真真梳理一遍自动装配原理

    前言 Spring翻译为中文是“春天”,的确,在某段时间内,它给Java开发人员带来过春天,但是随着我们项目规模的扩大,Spring需要配置的地方就越来越多,夸张点说,“配置两小时,Coding五分钟 ...

  6. 你来说一下springboot的启动时的一个自动装配过程吧

    前言 继续总结吧,没有面试就继续夯实自己的基础,前阵子的在面试过程中遇到的各种问题陆陆续续都会总结出来分享给大家,这次要说的也是面试中被问到的一个高频的问题,我当时其实没答好,因为很早之前是看到spr ...

  7. Spring(3)——装配 Spring Bean 详解

    装配 Bean 的概述 前面已经介绍了 Spring IoC 的理念和设计,这一篇文章将介绍的是如何将自己开发的 Bean 装配到 Spring IoC 容器中. 大部分场景下,我们都会使用 Appl ...

  8. 使用Spring IoC进行Bean装配

    Spring概述 Spring的设计严格遵从的OCP(开闭原则),保证对修改的关闭,也就是外部无法改变spring内部的运行流程:提供灵活的扩展接口,也就是可以通过extends,implements ...

  9. 002-Spring4 快速入门-项目搭建、基于注解的开发bean,Bean创建和装配、基于注解的开发bean,Bean初始化销毁、Bean装配,注解、Bean依赖注入

    一.项目搭建 1.项目创建 eclipse→project explorer→new→Project→Maven Project 默认配置即可创建项目 2.spring配置 <dependenc ...

随机推荐

  1. OpenStack Nova 高性能虚拟机之 NUMA 架构亲和

    目录 文章目录 目录 写在前面 计算平台体系结构 SMP 对称多处理结构 NUMA 非统一内存访问结构 MPP 大规模并行处理结构 Linux 上的 NUMA 基本对象概念 NUMA 调度策略 获取宿 ...

  2. delphi DLL image 动态绘图 句柄处理

    在调用DLL 动态在T Image 绘图时,传入  Image.Canvas.Handle 后,却总是绘不上,有时偶尔能绘上,却没搞清原因,而同样的代码,传入窗体的 Handle ,绘图却正常. 经过 ...

  3. java中? extends T 和? super T解析

    转:https://blog.csdn.net/qq_25337221/article/details/81669630 PECS原则 最后看一下什么是PECS(Producer Extends Co ...

  4. golang 千位分隔符

    项目需求将统计出的数字以千位分隔符分隔的形式展示(如将 1234567.89 格式化为 1,234,567.89),而 golang 的标准库中并无这样的函数. 万能的 google 找到解决办法,可 ...

  5. eclipse和myeclipse怎么在项目中查找指定代码?https://www.jb51.net/softjc/554889.html

    有的童鞋,想eclipse和myeclipse整个项目中查找指定代码,由于补经常使用,可能会补熟悉.如果要去掉项目中所有的某个代码的话,找不到是灰常麻烦的,下面就简单说下怎么查找,希望对需要的人有用. ...

  6. 【Linux 应用编程】进程管理 - 进程、线程和程序

    基本概念 程序和进程的区别 程序是平台相关的二进制文件,只占用磁盘空间.编写完程序代码后,编译为可执行的二进制文件即可. 进程是运行中的程序,占用 CPU.内存等系统资源. 通过 Shell 命令,可 ...

  7. proteus 与 keil 的安装及联调

    proteus 安装 Win10 系统的下载链接可以参考这里:https://tieba.baidu.com/p/5644915130?traceid= 百度网盘地址 链接1: http://pan. ...

  8. Servlet生命周期 Servlet获取配置信息 ServletContext

    一.Servlet生命周期 实例化 ——> 初始化 ——>  服务 ——>  销毁 出生:(实例化 然后 初始化)tomcat第一次访问,Servlet就出生(默认情况下) 活着:( ...

  9. Slience is the sleep that nourishes wisdom

    cumulative: 积聚的 lag. v. 落后 backfire. n. 事与愿违 segregated. adj. 分隔的 back-and-forth: 来回地 initiative. ad ...

  10. 初学node.js-nodejs中实现用户登录路由

    经过前面几次的学习,已经可以做下小功能,今天要实现的事用户登录路由. 一.users_model.js  功能:定义用户对象模型 var mongoose=require('mongoose'), S ...