Spring IOC 常用的注解

一、@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、指定@Scopeprototype 表示为多实例的,而且还是懒汉模式加载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接口






 

猜你喜欢

转载自www.cnblogs.com/yufeng218/p/12040957.html