Summary:
In normal development, do not know if you have not thought about such a problem, why do we custom annotation when you want to use native Notes spring of (in this case is similar @Component
, @Service
........), or is just get hold of the notes, with their cut programming to achieve certain business logic. This article to share with you, and how to escape Spring原生注解
custom annotation injectionIOC
SpringBootApplication analysis notes
From the source code is easy to see, it is the role of automatic assembly and scan our package and conforming to the container type to be registered. Automatic assembly is very simple, do not do too much analysis here, then analyze what is called 符合规则的类
. In the @ComponentScan
filter of the type defined above annotations
public enum FilterType {
ANNOTATION, //注解类型
ASSIGNABLE_TYPE, //指定的类型
ASPECTJ, //按照Aspectj的表达式,基本上不会用到
REGEX, //按照正则表达式
CUSTOM; //自定义
private FilterType() {
}
}
Exclusion filters excludeFilters
This class is for us to exclude matching, let him registered to IOC
the use of the time, Springboot use two filters to exclude default, a very simple, casual search online you can find instructions, here I give Teshu Liezi on the line a.
package com.github.dqqzj.springboot.filter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author qinzhongjian
* @date created in 2019-07-30 19:14
* @description: TODO
* @since JDK 1.8.0_212-b10
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dqqzj {
String value();
}
package com.github.dqqzj.springboot.filter;
import org.springframework.stereotype.Component;
/**
* @author qinzhongjian
* @date created in 2019-07-29 22:30
* @description: TODO
* @since JDK 1.8.0_212-b10
*/
@Dqqzj(value = "dqqzj")
@Component
public class Tt {
}
package com.github.dqqzj.springboot.filter;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;
/**
* @author qinzhongjian
* @date created in 2019-07-30 19:13
* @description: TODO
* @since JDK 1.8.0_212-b10
*/
public class MyTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
if (metadataReader.getAnnotationMetadata().isAnnotated(Dqqzj.class.getName())) {
return true;
}
return false;
}
}
The above code is normal logic, in turn, I thought that if the Tt
class @Component
notes are not also remove the line, so this exclusion notes are generally used in normal can be injected into the container when to add, and then we said above, from the Spring
It can also be injected into the container, how to achieve it?
includeFilters filter comprising
From Spring原生注解
the the Tt
class @Component
annotation removed
package com.github.dqqzj.springboot.filter;
import org.springframework.stereotype.Component;
/**
* @author qinzhongjian
* @date created in 2019-07-29 22:30
* @description: TODO
* @since JDK 1.8.0_212-b10
*/
@Dqqzj(value = "dqqzj")
//@Component
public class Tt {
}
Look beyond the surface
Processes comb, annotation-driven injection at a critical scanning type container (note that this is referring to the scan, rather than what @ Bean, @ Import and other remaining notes are built on the basis of)
- ComponentScanAnnotationParser
- ClassPathBeanDefinitionScanner
- ClassPathScanningCandidateComponentProvider
ClassPathScanningCandidateComponentProvider#registerDefaultFilters
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false));
this.logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
} catch (ClassNotFoundException var4) {
}
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false));
this.logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
} catch (ClassNotFoundException var3) {
}
}
Here will be @Component
, JSR-250 'javax.annotation.ManagedBean'
, JSR-330 'javax.inject.Named'
annotations register, so no wonder our custom annotation must have derived these notes, from a different angle to think that this place be like AnnotationTypeFilter
to add, we can also customize AnnotationTypeFilter
to your own definition of the rules the notes were injected into the container.