Springboot自动装配实现过程代码实例
作者:Zs夏至 时间:2023-11-14 19:50:19
创建一个简单的项目:
<?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
标签:Spring,boot,自动,装配
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Android多边形区域扫描线种子填充算法的示例
2023-05-25 00:27:24
![](https://img.aspxhome.com/file/2023/3/137333_0s.gif)
C#监测IPv4v6网速及流量的实例代码
2021-10-29 09:54:41
![](https://img.aspxhome.com/file/2023/8/100228_0s.png)
聊聊Java的switch为什么不支持long
2023-08-24 17:35:14
Spring Boot 整合持久层之Spring Data JPA
2022-07-29 04:00:38
![](https://img.aspxhome.com/file/2023/9/62689_0s.png)
通过OpenGL ES混合模式缩放视频缓冲区来适应显示尺寸
2023-11-07 15:56:41
![](https://img.aspxhome.com/file/2023/4/119084_0s.jpg)
不使用他人jar包情况下优雅的进行dubbo调用详解
2022-04-20 11:43:46
JAVA反射机制实例教程
2023-11-25 23:33:47
浅谈spring security入门
2023-02-20 04:48:58
![](https://img.aspxhome.com/file/2023/2/63782_0s.png)
浅析JAVA中过滤器、监听器、拦截器的区别
2023-10-18 17:47:24
Redis缓存,泛型集合与json字符串的相互转换实例
2021-07-18 16:57:15
![](https://img.aspxhome.com/file/2023/9/136629_0s.jpg)
Java实现微信公众号发送模版消息
2021-07-16 17:03:35
![](https://img.aspxhome.com/file/2023/7/79337_0s.jpg)
C#获取指定目录下指定文件的方法
2022-11-01 12:34:27
Android编程实现类似天气预报图文字幕垂直滚动效果的方法
2022-08-02 08:16:50
![](https://img.aspxhome.com/file/2023/9/122119_0s.gif)
给c#添加SetTimeout和SetInterval函数
2021-07-02 00:58:08
![](https://img.aspxhome.com/file/2023/7/77237_0s.png)
C#异常捕获机制图文详解
2023-05-22 19:39:20
![](https://img.aspxhome.com/file/2023/5/116445_0s.png)
java基础的详细了解第三天
2023-10-05 23:47:04
![](https://img.aspxhome.com/file/2023/9/84609_0s.png)
LZ77压缩算法原理的理解
2023-01-16 17:48:02
![](https://img.aspxhome.com/file/2023/5/127505_0s.png)
Android集成Flutter
2023-07-06 13:07:33
![](https://img.aspxhome.com/file/2023/0/101830_0s.jpg)
opencv配置的完整步骤(win10+VS2015+OpenCV3.1.0)
2023-06-28 14:55:19
![](https://img.aspxhome.com/file/2023/4/100304_0s.png)
dotnet core链接mongodb代码实例
2023-07-20 14:26:09