Springboot自动装配实现过程代码实例
作者:Zs夏至 发布时间:2023-11-14 19:50:19
标签:Spring,boot,自动,装配
创建一个简单的项目:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.1.12.RELEASE</version>
</parent>
<groupId>com.xiazhi</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
首先创建自定义注解:
package com.xiazhi.demo.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* MyComponent 作用于类上,表示这是一个组件,于component,service注解作用相同
* @author zhaoshuai
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyComponent {
}
package com.xiazhi.demo.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 作用于字段上,自动装配的注解,与autowired注解作用相同
* @author zhaoshuai
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Reference {
}
然后写配置类:
package com.xiazhi.demo.config;
import com.xiazhi.demo.annotation.MyComponent;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
/**
* @author ZhaoShuai
* @company lihfinance.com
* @date Create in 2020/3/21
**/
public class ComponentAutoConfiguration implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
private ResourceLoader resourceLoader;
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
String className = annotationMetadata.getClassName();
String basePackages = className.substring(0, className.lastIndexOf("."));
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry, false);
scanner.addIncludeFilter(new AnnotationTypeFilter(MyComponent.class));
scanner.scan(basePackages);
scanner.setResourceLoader(resourceLoader);
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
上面是配置扫描指定包下被MyComponent注解标注的类并注册为spring的bean,bean注册成功后,下面就是属性的注入了
package com.xiazhi.demo.config;
import com.xiazhi.demo.annotation.MyComponent;
import com.xiazhi.demo.annotation.Reference;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
/**
* @author ZhaoShuai
* @company lihfinance.com
* @date Create in 2020/3/21
**/
@SpringBootConfiguration
public class Configuration implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Bean
public BeanPostProcessor beanPostProcessor() {
return new BeanPostProcessor() {
/**
* @company lihfinance.com
* @author create by ZhaoShuai in 2020/3/21
* 在bean注册前会被调用
* @param [bean, beanName]
* @return java.lang.Object
**/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* @company lihfinance.com
* @author create by ZhaoShuai in 2020/3/21
* 在bean注册后会被加载,本次在bean注册成功后注入属性值
* @param [bean, beanName]
* @return java.lang.Object
**/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Class<?> clazz = bean.getClass();
if (!clazz.isAnnotationPresent(MyComponent.class)) {
return bean;
}
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (!field.isAnnotationPresent(Reference.class)) {
continue;
}
Class<?> type = field.getType();
Object obj = applicationContext.getBean(type);
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, bean, obj);
}
return bean;
}
};
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
下面开始使用注解来看看效果:
package com.xiazhi.demo.service;
import com.xiazhi.demo.annotation.MyComponent;
import javax.annotation.PostConstruct;
/**
* @author ZhaoShuai
* @company lihfinance.com
* @date Create in 2020/3/21
**/
@MyComponent
public class MyService {
@PostConstruct
public void init() {
System.out.println("hello world");
}
public void test() {
System.out.println("测试案例");
}
}
package com.xiazhi.demo.service;
import com.xiazhi.demo.annotation.MyComponent;
import com.xiazhi.demo.annotation.Reference;
/**
* @author ZhaoShuai
* @company lihfinance.com
* @date Create in 2020/3/21
**/
@MyComponent
public class MyConsumer {
@Reference
private MyService myService;
public void aaa() {
myService.test();
}
}
启动类要引入配置文件:
import注解引入配置文件。
编写测试类测试:
@SpringBootTest(classes = ApplicationRun.class)
@RunWith(SpringRunner.class)
public class TestDemo {
@Autowired
public MyConsumer myConsumer;
@Test
public void fun1() {
myConsumer.aaa();
}
}
来源:https://www.cnblogs.com/Zs-book1/p/12540571.html


猜你喜欢
- 相关概念1.Handler:可以看做是一个工具类,用来向消息队列中插入消息的;2.Thread:所有与Handler相关的功能都是与Thre
- RecyclerView是什么 RecycleView是Androi
- spring boot 请求后缀匹配spring boot 项目中添加这个类可以实现url不同后缀区分了public class UrlMa
- 析构函数用于析构类的实例。备注不能在结构中定义析构函数。只能对类使用析构函数。一个类只能有一个析构函数。无法继承或重载析构函数。无法调用析构
- AlarmManager通常用来开发手机闹钟,并且它是一个全局定时器,可在指定时间或指定周期启动其他组件(包括Activity,Servic
- 一Map特性:1 Map提供一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value;2
- 实例如下://首先要添加 System.ServiceProcess.dll 引用 ServiceController sc
- 稍微深入了解过Android的开发者都知道,Android中每个APP的中的所有组件的生命周期状态都是由ActivityManagerSer
- clone()和Cloneable接口clone顾名思义就是克隆,即,复制一个相等的对象,但是不同的引用地址。我们知道拿到一个对象的地址,只
- 本文实例讲述了android从资源文件中读取文件流并显示的方法。分享给大家供大家参考。具体如下:在android中,假如有的文本文件,比如T
- #define只加一个参数 的解释<stdio.h> 里有:#ifndef __STDIO_H #define &n
- 资源服务器就是业务服务 如用户服务,订单服务等 第三方需要到资源服务器调用接口获取资源ResourceServerConfigResourc
- 问题描述最近IDEA抽风了,不管是新建SpringBoot工程,还是导入项目。IDEA代码里面都会飘红~Build项目时,会提示错误:错误:
- 一、select是什么select——>用于选择更快的结果。基于场景理解比如客户端要查询一个商
- C#一些延时函数sleep延时方法System.Threading.Thread.Sleep(1000); //毫秒实现的是非独占性延时函数
- 本文实例为大家分享了C#实现QQ聊天窗口的具体代码,供大家参考,具体内容如下效果图:using System;using System.Co
- 登录接口实现public User queryUser(String UserName, String Password,HttpServl
- ListView是开发中最常用的控件了,但是总是会写重复的代码,浪费时间又没有意义。最近参考一些资料,发现一个万能ListView适配器,代
- 开发过程中经常用到加载圈,特别是车机开发由于外设不同很多操作响应的等待时长经常要用到不同的加载圈。首先,直接上菊花效果图,这是我直接从项目里
- 新建一个集合List<Bill> billList = new ArrayList<>();将订单中所有物品的名称提