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. Java中class的声明

    在Java中下面Class的声明哪些是错误的?(A,B,C)   A:public abstract final class Test { abstract void method();} B:pub ...

  2. Stream之filter、distinct、skip、map、flatMap、match、find、reduce

    一.Stream之filter.distinct.skip: package com.cy.java8; import java.util.Arrays; import java.util.List; ...

  3. java网络通信:伪异步I/O编程(PIO)

    缺点:避免了线程资源耗尽的问题,但是根本上来说,serversocket的accept方法和inputstream的输入流方法都是阻塞型方法. 服务端:加了一个线程池,实现线程复用.客户端不变 pub ...

  4. 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第1节 基本概念_03maven一键构建概念

    资料里面写好的Helloworld项目 pom.xml存放jar包的坐标 首先复制项目所在的目录的路径: 先进去复制的这个路径,然后又输入了d盘.这时候就进去到这个项目目录了. 这个项目就运行起来了. ...

  5. 【Windows Server存储】windows文件系统

    windows文件系统 弹性文件系统(ReFS) 无检查磁盘,Windows 8或Windows Server 2012以上运行. 参考资料表明,这是一个失败的文件系统,以后将不会商用. 参考资料:h ...

  6. 简述Vue的路由与视图

    1.vue-router 安装方式 npm/cnpm:(个人偏向于cnpm) npm/cnpm install vue-router --save-dev bower: bower install v ...

  7. notepad++通过调用cmd运行java程序

    notepad++运行java程序方法主要有下面两个: 通过插件NppExec运行(自行百度“notepad++运行java”) 通过运行 调用cmd编译执行java程序(下面详细讲解) 点击上面工具 ...

  8. python爬取b站排行榜

    爬取b站排行榜并存到mysql中 目的 b站是我平时看得最多的一个网站,最近接到了一个爬虫的课设.首先要选择一个网站,并对其进行爬取,最后将该网站的数据存储并使其可视化. 网站的结构 目标网站:bil ...

  9. OpenGL字体绘制

    /* glfont.hpp sdragonx 2019-08-15 00:03:33 opengl字体类,提供初学者参考学习 opengl初始化之后,创建字体 font.init(L"微软雅 ...

  10. Period II

    For each prefix with length P of a given string S,if S[i]=S[i+P] for i in [0..SIZE(S)-p-1], then the ...