- 1、@AliasFor :定义别名
源码:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface AliasFor {
@AliasFor("attribute")
String value() default "";
@AliasFor("value")
String attribute() default "";
Class<? extends Annotation> annotation() default Annotation.class;
}
给扫描器指定规则 :
① 三层组件
1、ANNOTATION: 默认值,三层注解类型@Controller、@Service、@Repository -> @Component
2、excludeFilters:排除类,类型类枚举类型, 通过注解可查看类型
//扫描 org.zq 包下的@Component等注解 ,并排除 Service.class, Repository.class
@ComponentScan(value = "org.zq",
excludeFilters ={
@ComponentScan.Filter(type = FilterType.ANNOTATION,
value = {Service.class, Repository.class})
})
3、ASSIGNABLE_TYPE:值得是具体的一个类 如 StudentController.class
4、includeFilters:有默认行为,可以通过useDefaultFilters = false 禁止
//扫描 org.zq 包下的 StudentController.class 类纳入IOC容器
@ComponentScan(value = "org.zq", useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {StudentController.class}))
5、CUSTOM :自己定义包含规则
- 实现 TypeFilter 重写其中的match,如果return true则加入IoC容器
public class MyFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
ClassMetadata classMetadata = metadataReader.getClassMetadata();//获取元信息
// 扫描器扫描“org.zq”包中所有的类 ,getClassName() 可以拿到该包中所有类的名字(只有三层)
String className = classMetadata.getClassName();
//如果className包含School 则加入ioc容器
if(className.contains("School")){
return true;
}
return false;
}
}
配置类中 使用
@ComponentScan(value = "org.zq", useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(
type = FilterType.CUSTOM, value = {MyFilter.class}
))
② 非三层组件
- i. @Bean+方法的返回值 ,id 默认 是方法名(可以通过@Bean(“stu”) 修改id值)
@Bean("stu")
public Student myStudent() {
return new Student("ls", 23);
}
- ii. import(三种方式) 、FactoryBean
1、 import方式一 :@Import({Student.class}) // 需要一个 Class类型的数组
2、 import方式二 : 编写一个类 实现 ImportSelector 接口 ,并 通过方式一讲导入类引入
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{ Student.class.getName() }; //必须给全类名
}
}
在配置类中导入
@Import(MyImportSelector.class)
3、 import方式三 : 编写一个类 实现 ImportBeanDefinitionRegistrar 接口 ,并 通过方式一讲导入类引入
public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition root = new RootBeanDefinition(Student.class);
registry.registerBeanDefinition("student",root);
}
}
4、FactoryBean方式
1、实现FactoryBean 接口
public class MyFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new Student();
}
@Override
public Class<?> getObjectType() {
return Student.class;
}
@Override
public boolean isSingleton() {
return false;//是否是单例
}
}
@Bean
public FactoryBean<Student> student(){
return new MyFactoryBean(); //到底放的是哪一个对象 & 区分
}
Test
Object apple = context.getBean("&student"); //获取的是MyFactoryBean的实例
Object apple = context.getBean("student"); //获取的是Student的实例
总结
bean: 类
a. 非三层组件 :Student\Teacher\配置信息 : @Bean
b. 三层组件 :Controller、Service、Dao :@Component(@Controller、@Service、@Repository)
三层组件
a.加入@Component等注解
b.配置,让容器识别注解
- i.XML形式:通过扫描器 将@Component等注解所在包 扫描
<context:component-scan base-package=" 包名 " ></context:component-scan>
- ii.注解
@Configuration
@ComponentScan(value="包名")
public class MyConfig {...}
component-scan指定规则:
FilterType :
- ANNOTATION:指定类型 (@Compent @Controller @Service @Repository)
- ASSIGNABLE_TYPE :自定义类的类中选 StudentDao
- ASPECTJ,
- REGEX,
- CUSTOM:自定义形式 :
a.@ComponentScan.Filter(type= FilterType.CUSTOM,classes ={ MyFilter.class})},useDefaultFilters = false)
b.MyFilter implements TypeFilter 重写match()方法,如果返回值true
@Component(@Controller、@Service、@Repository):三层组件
非三层组件