SpringBoot框架(4)-- 类装配及Bean装配监听器
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装配监听器的更多相关文章
- Bean 装配,从 Spring 到 Spring Boot
目录 从SSM的集成谈到Bean的装配 Bean的装配 由XML到Java Config 自动扫描 Bean的注入 SSM集成的Java版 Spring Boot Magic Auto Confi ...
- Spring对Bean装配详解
1.Spring提供了三种装配bean的方式: 2.自动装配bean: 3.通过Java代码装配bean 4.通过XML装配bean 前言:创建对象的协作关系称为装配,也就是DI(依赖注入)的本质.而 ...
- SpringBoot框架(3)--条件装配
场景:需要根据系统的编码格式有选择装配类. 分析:最直接的实现方式,定义各种编码格式对应的处理类,可以通过System.getProperty("file.encoding")获得 ...
- 使用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...”. 原 ...
- SpringBoot:认认真真梳理一遍自动装配原理
前言 Spring翻译为中文是“春天”,的确,在某段时间内,它给Java开发人员带来过春天,但是随着我们项目规模的扩大,Spring需要配置的地方就越来越多,夸张点说,“配置两小时,Coding五分钟 ...
- 你来说一下springboot的启动时的一个自动装配过程吧
前言 继续总结吧,没有面试就继续夯实自己的基础,前阵子的在面试过程中遇到的各种问题陆陆续续都会总结出来分享给大家,这次要说的也是面试中被问到的一个高频的问题,我当时其实没答好,因为很早之前是看到spr ...
- Spring(3)——装配 Spring Bean 详解
装配 Bean 的概述 前面已经介绍了 Spring IoC 的理念和设计,这一篇文章将介绍的是如何将自己开发的 Bean 装配到 Spring IoC 容器中. 大部分场景下,我们都会使用 Appl ...
- 使用Spring IoC进行Bean装配
Spring概述 Spring的设计严格遵从的OCP(开闭原则),保证对修改的关闭,也就是外部无法改变spring内部的运行流程:提供灵活的扩展接口,也就是可以通过extends,implements ...
- 002-Spring4 快速入门-项目搭建、基于注解的开发bean,Bean创建和装配、基于注解的开发bean,Bean初始化销毁、Bean装配,注解、Bean依赖注入
一.项目搭建 1.项目创建 eclipse→project explorer→new→Project→Maven Project 默认配置即可创建项目 2.spring配置 <dependenc ...
随机推荐
- flask环境布署--废弃不用,只留作备份
[前置条件] 创建1个flask-demo,生成requirement.txt文件(下载好gunicorn),上传至git.创建demo参照:创建一个flask api-demo(响应体显示中文) g ...
- Leon-ai on WSL
这几天尝试了下Windows10的WSL,的确是良心产品,虽然还有很多待改进的地方(比如iptabeles之类的功能还未支持). 使用了WSL就避免安装双系统的繁琐,节省很多时间,而且因为是微软自家产 ...
- 20191110 Spring Boot官方文档学习(3)
3.使用Spring Boot 3.1.构建系统 建议选择Maven或Gradle作为构建工具 每个Spring Boot版本都提供了它所支持的依赖关系的精选列表.实际上,您不需要为构建配置中的所有这 ...
- MySql 性能优化之 Explain
MySQL 之 Explain 输出分析 背景 前面的文章写过 MySQL 的事务和锁,这篇文章我们来聊聊 MySQL 的 Explain,估计大家在工作或者面试中多多少少都会接触过这个.可能工作中实 ...
- 刘铁猛-深入浅出WPF-系列资源汇总
首先奉上原作者刘铁猛博客地址:http://www.cnblogs.com/prism/ 作者讲的很不错,没有之一,另外作者出了一本书,希望大家支持. 送上全套高清晰视频教程(我注册了3个51cto的 ...
- docker私有仓库-harbor
简单说一下Harbor的部署,踩了几个坑,参考同事大神的配置文件,一脸懵逼的部署出来了,其中部分内容参考了网上一些大神的文档,本篇文章仅供参考学习,如有雷同,万分荣幸. 这篇文档仅限于centos7参 ...
- 第十四周总结 Io之文件流
I/O相关 输入/输出 流(数据流动) 数据流动的方向 读数据(输入input) 写数据(输出output) 文件流 字符流 数据流 对象流 网络流.... 1.什么叫文件 一种电脑的存储方式 文件有 ...
- 多线程14-Barrier
, b => Console.WriteLine()); ; i <= ; i++) { Console.Write ...
- spring扩展点之PropertyPlaceholderConfigurer
原理机制讲解 https://leokongwq.github.io/2016/12/28/spring-PropertyPlaceholderConfigurer.html 使用时多个配置讲解 ht ...
- C++中的函数重载分析(一)
1,重载是 C 语言到 C++ 语言的一个飞跃,C 语言中没有重载的概念,所有的函数 名是不允许有重复的,在 C++ 中因为引进了重载,所以函数名可以重复: 2,自然语言中的上下文: 1,你知道上面词 ...