一、ioc
1、@Configuration和@Bean会给ioc容器加载 组件
2、@ComponentScan会给容器扫描一些文件,并将@Controller@Repos...@Service扫描到ioc容器,使用
@ComponentScan(value="com.atguigu",excludeFilters = {
@ComponentScan.Filter(type= FilterType.ANNOTATION,classes = {Controller.class, Service.class})
},includeFilters = {
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class})
//assignable_type 指定的类型,annotation 指定的注解类型
// useDefaultFilters 用户默认滤器 false才能include
},useDefaultFilters = false)
可以选择需要加载的组件
如果需要自定义扫描方式可以在includeFilter中增加一个CUSTOM的过滤器
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})},
然后新建一个MyTypeFilter实现TypeFilter类,
//MetadataReader :当前类信息 MetadataReaderFactory:获取到其他类信息的
public class MyTypeFilter implements TypeFilter {
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//当前类所有的注解
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//当前扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//当前扫描类的资源信息(路径等)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("当前扫描的类有"+className);
if(className.contains("com")){
return true;
}
return false;
}
}
3、@conditional注解
@conditional注解的含义是实现了某种条件下才去将这个实例加入到ioc容器中
首先应该有实现condition的条件类,WindowsCondition 中match方法中的判断返回的是真还是假,会成为@conditional判断的依据。
public class WindowsCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String osname = environment.getProperty("os.name");
System.out.println(osname);
if (!osname.equals("") && osname.contains("Windows")) {
return true;
}
return false;
}
}
然后在配置类上加上@conditional(WindowConditon.class)注解,当运行环境是window时这个条件为真,这个组件就被添加到ioc容器中。
4、@Import 在配置类上加@Import(XXX.class),就可以将XXX.class组件加到ioc容器中,除了xxx.class 还可以加入加入实现了ImportSelector的组件,第三种是实现ImportBeanDefinitionRegistrar接口。直接注册一个组建。具体的海马如下
@Configuration
@Import({Color.class,MyImportSelector.class, MyBeanDefinitionRegistry.class})
public class MyConfig2 {
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.atguigu.bean.Red","com.atguigu.bean.Yellow"};
// return null;
}
}
public class MyBeanDefinitionRegistry implements ImportBeanDefinitionRegistrar {
//AnnotationMetadata :@import注解的所有信息,注解和方法和属性等等
//BeanDefinitionRegistry 注册器 往ioc里加组件的
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean color = registry.containsBeanDefinition("com.atguigu.bean.Color");
if(color){
//注册bean
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
registry.registerBeanDefinition("rainbow",beanDefinition);
}
}
}
5、FactoryBean 这个类被实现的时候有个方法可以直接创建一个具体类的实例,
public class ColorFactoryBean implements FactoryBean {
public Object getObject() throws Exception {
//实际上要添加的组件
return new Color();
}
public Class<?> getObjectType() {
return null;
}
public boolean isSingleton() {
return true;
}
}
然后在具有@configration的配置类中写一个带有@Bean的配置方法返回一个FactoryBean,实际返回的就是getObject()方法创建的实例
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}