一、核心容器
1.包扫描
自定义包含规则:(也可以指定排除规则)
@Configuration
@ComponentScan(value="org.jcut",includeFilters= {
//@Filter(type=FilterType.ANNOTATION,classes= {Controller.class}),
@Filter(type=FilterType.CUSTOM,classes= {MyFilter.class})
},useDefaultFilters=false)
public class AnnoConfig {
@Bean("person")
public Student person() {
return new Student("zhangsan", 12);
}
}
//自定义过滤器
public class MyFilter implements TypeFilter {
@Override
public boolean match(MetadataReader arg0, MetadataReaderFactory arg1) throws IOException {
ClassMetadata classMetadata = arg0.getClassMetadata();
String className = classMetadata.getClassName();
//类名包含“er”的类则放行。
if (className.contains("er")) {
return true;
}
return false;
}
}
2.作用域
作用域为单例的时候,启动容器即会生成bean对象,而在peototype时,只有在调用方法时,即下面一句话的时候才会生成bean对象。
// Object bean = applicationContext.getBean(“person”);
public class AnnoConfig2 {
@Scope("singleton")
//@Scope("prototype")
@Bean("person")
public Student person() {
System.out.println("容器中添加了person");
return new Student("zhangsan", 12);
}
}
懒加载:@lazy注解,使得在第一次方法调用的时候才生成bean对象。
3.按条件注册bean:@Conditional
public @interface Conditional {
public @interface Conditional {
//需要满足注册条件才能注册到容器中,要求Condition数组。
Class<? extends Condition>[] value();
}
案例:根据不同的系统运行环境注册bean
public class AnnoConfig2 {
@Conditional(WindowsCondition.class)
@Bean("bill")
public Person person01(){
return new Person("Bill Gates",62);
}
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person02(){
return new Person("linus", 48);
}
}
LinuxCondition需要实现condition接口
public class LinuxCondition implements Condition {
/**
* ConditionContext:判断条件能使用的上下文(环境)
* AnnotatedTypeMetadata:注释信息
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("linux")){
return true;
}
return false;
}
}
WindowCondition.java和这个代码基本相同:
public class Demo4 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnoConfig2.class);
ConfigurableEnvironment environment = applicationContext.getEnvironment();
//动态获取环境变量的值;Windows 10
String property = environment.getProperty("os.name");
System.out.println(property);
Map<String, Person> persons =applicationContext.getBeansOfType(Person.class);
System.out.println(persons);
}
}
模拟linux环境:
运行结果:
{linus=Person [name=张三, age=18]}
4.三种注册bean的方式
演示ImportSelector使用
@Configuration
@Import(value = {Blue.class,MyImportSelector.class })
public class Config3 {
}
我们想要使用自定义MyInpoertSelector的方式将其他的bean进行加载:
public class MyImportSelector implements ImportSelector {
//要求返回数组
@Override
public String[] selectImports(AnnotationMetadata metadata) {
String name = Green.class.getName();
String name2 = Red.class.getName();
return new String[] {name,name2};
}
}
使用ImportBeanDefinitionRegistrar手动注册
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/* AnnotationMetadata:当前类的注解信息
BeanDefinitionRegistry : BeanDefinition注册类;
把所有需要添加到容器中的bean;调用
BeanDefinitionRegistry. registerBeanDefinition手工注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
boolean definition1= registry.containsBeanDefinition("org.jcut.bean.Blue");
boolean definition2=registry.containsBeanDefinition("org.jcut.bean.Green");
//如果有Blue和Green类就注册RainBow类
if (definition1&&definition2) {
BeanDefinition beanDefinition=new RootBeanDefinition(RainBow.class);
registry.registerBeanDefinition("rainBow", beanDefinition);
}
}
}
//注册类
public class Config3 {
@Bean("colorFactoryBean")
public ColorFactoryBean colorFactoryBean() {
//注意这里
return new ColorFactoryBean();
}
}
//测试
public class Demo7 {
public static void main(String[] args) {
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(Config3.class);
Object bean1 = configApplicationContext.getBean("colorFactoryBean");
Object bean2 = configApplicationContext.getBean("colorFactoryBean");
System.out.println(bean1);
System.out.println(bean1==bean2);
}
}
结果:
org.jcut.bean.Color@1e4a7dd4
true
可以看出,调用colorFactoryBean的bean时,却得到的是Color的实例,要想得到colorFactoryBean对象,需要使用&, 即Object bean1 = configApplicationContext.getBean("&colorFactoryBean");