一、@Bean
1、配置类
@Configuration
public class MainConfig
{
@Bean
public Person person(){
return new Person();
}
}
注意:通过@Bean的形式是使用的话, bean的默认名称是方法名,可以使用 @Bean(value="bean的名称") 去指定bean的名称;
2、测试类:
public class MainClass
{
public static void main(String[] args)
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
//Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);
System.out.println(ctx.getBean("person"));
}
}
二、@ComponentScan
在配置类上增加 @ComponentScan 注解,来进行包扫描;
@ComponentScan 注解 配合 @Controller、@Service、@Component、@Reposity 使用,将类注册到IOC容器中;
1、basePackages 包扫描的路径
@Configuration
//扫描com.yufeng.componentscan包下的所有
@ComponentScan(basePackages = {"com.yufeng.componentscan"})
public class MainConfig {
}
2、excludeFilters,排除
(a)FilterType.ANNOTATION : 排除注解
(b)FilterType.ASSIGNABLE_TYPE:排除具体的类
@Configuration
//扫描com.yufeng.componentscan包下的所有, 排除有@Controller注解的类, 排除类TuService
@ComponentScan(basePackages = {"com.yufeng.componentscan"},
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {TuService.class})})
public class MainConfig {
}
(c)FilterType.CUSTOM:自定义规则去排除
@Configuration
//扫描com.yufeng.componentscan包下的所有, 按照自定义规则排除
@ComponentScan(basePackages = {"com.yufeng.componentscan"},
excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, value = {MyTypeFilter.class})})
public class MainConfig {
}
自定义的规则(实现 TypeFilter 接口):类名中包含dao的需要排除
public class MyTypeFilter implements TypeFilter
{
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException
{
//获取当前类的注解源信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前类的class的源信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类的资源信息
Resource resource = metadataReader.getResource();
System.out.println("类的路径:"+classMetadata.getClassName());
if(classMetadata.getClassName().contains("dao")) {
return true; //返回true, 则需要去过滤掉, 所以类名中包含dao的类不会被加载到IOC容器中
}
return false;
}
}
3、includeFilters 包含,在包扫描的当前路径下只加载 includeFilters 包含的,其他的不加载;
注意:需要把 useDefaultFilter 属性设置为 false (true表示全表扫描)
@Configuration
//--------------包含 includeFilters -------------
@ComponentScan(basePackages = {"com.yufeng.componentscan"},
includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {Person.class})},
useDefaultFilters = false)
public class MainConfig{
}
4、测试类
public class MainClass {
public static void main(String[] args)
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
Arrays.stream(ctx.getBeanDefinitionNames())
.forEach(name -> System.out.println("bean的自定义: " + name));
ctx.close();
}
}
三、配置Bean的作用域对象
1、在不指定 @Scope 的情况下,所有的bean都是单实例的bean,而且是饿汉加载(容器启动实例就创建好了)
@Bean
public Person person() {
return new Person();
}
2、指定@Scope为 prototype 表示为多实例的,而且还是懒汉模式加载(IOC容器启动的时候,并不会创建对象,而是在第一次使用的时候才会创建)
@Bean
@Scope(value = "prototype")
public Person person() {
return new Person();
}
3、@Scope指定的作用域方法取值
(a)singleton 单实例的(默认)
(b)prototype 多实例的
(c)request 同一次请求
(d)session 同一个会话级别
单实例的Bean要实现懒加载,可以使用 @Lazy 注解 (主要针对单实例的bean 容器启动的时候,不创建对象,在第一次使用的时候才会创建该对象)
@Bean @Lazy public Person person() { return new Person(); }
四、@Conditional 进行条件判断
有二个组件TulingAspect 和 TulingLog ,我的TulingLog组件是依赖于TulingAspect的组件
应用:自己创建一个TulingCondition的类 实现Condition接口