Springboot自動組立実現プロセスコード例
簡単なアイテムを作成します。
importコメントはプロファイルを導入します。
試験類の編纂テスト:
<?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();
}
}
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。