Springboot自動裝配實現(xiàn)過程代碼實例
更新時間:2020年06月11日 09:41:34 作者:Zs夏至
這篇文章主要介紹了Springboot自動裝配實現(xiàn)過程代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
創(chuàng)建一個簡單的項目:
<?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>
首先創(chuàng)建自定義注解:
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注冊前會被調(diào)用
* @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();
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java中動態(tài)設(shè)置JVM參數(shù)的方法總結(jié)
通過動態(tài)設(shè)置JVM參數(shù),開發(fā)者可以更有效地管理資源使用和優(yōu)化性能,本文將詳細闡述如何在Java中動態(tài)設(shè)置JVM參數(shù),感興趣的小伙伴可以了解下2024-12-12
Springboot實現(xiàn)Java郵件任務(wù)過程解析
這篇文章主要介紹了Springboot實現(xiàn)Java郵件任務(wù)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09

