Spring注解详细测试

一、@componentScan注解

1、注册bean

    //给容器中注册一个bean;类型为返回值类型,id默认是用方法名作为id
	//如果@Bean("name"),则调用时是使用通过那么来获取
    @Bean("person")
    public Person person01(){
        return new Person("李四",20);
    }

2、新建配置类

//在新建类上加上注释@configura,
@Configuration//告诉spring这是一个配置类
//配置类就等于以前的配置文件

包扫描:

@ComponentScan(value = "com.atguigu",excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
})
//@ComponentScan value:指定要扫描的包
//excludeFilters = Filter[]

3、自定义FilterType

系统给定的类型有:

public enum FilterType {

	ANNOTATION,//按照注解形式

	ASSIGNABLE_TYPE,//按照给定的类型

	ASPECTJ,//使用aspectj表达式:基本不会使用

	REGEX,//正则表达式
    
	CUSTOM//使用自定义规则
}

自定义规则需要实现这个接口:

@FunctionalInterface
public interface TypeFilter {

//metadataReader:读取到当前正在扫描的类的信息
       // metadataReaderFactory:可以获取到其他任何类信息的
	boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException;

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QjhUxwUs-1597651405808)(/…/…/…/1.png)]

自定义的类如下:

public class MyTypeFilter implements TypeFilter {
    //metadataReader:读取到当前正在扫描的类的信息
    // metadataReaderFactory:可以获取到其他任何类信息的
    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);
        return false;

    }

在配置类添加使用(返回布尔值):

@ComponentScan(value = "com.atguigu",includeFilters = {
        @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})

结果:返回值为false;且还没有指定过滤类型,所以扫描的是全部的,但是未添加到容器

添加简单的自定义判断后:

 if(className.contains("er")){//类明含有er则添加到容器,否则不添加
            return true;
        }
        return false;

结果:myTypeFilter并不是组件但是也包含了[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XXk3P805-1597651405813)(/…/…/…/源码截图/1597647990719.png)]

二、@Scope设置组件作用域

    /**
     * prototype:多实例的
     * singleton:单实例的(默认值)
     * request:同一次请求创建一个实例
     * session:同一个session创建一个实例
     */
    @Scope()

1、测试单例下

        Object person = applicationContext.getBean("person");
        Object person2 = applicationContext.getBean("person");

        System.out.println(person==person2);

结果:

mainConfig2
person
true

2、测试多例模式下

 @Scope("prototype")

结果

mainConfig2
person
false

结论:

用@scope(prototype)控制作用范围:每次获取Bean的时候会有一个新的实例

3、探究何时将bean放入容器

单例模式下:
    @Scope()
    @Bean("person")
    public Person person(){
        System.out.println("给容器中添加Person...");
        return new Person("张三",25);
    }

结果:

给容器中添加Person...
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
person
多例模式下:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
person
给容器中添加Person...
给容器中添加Person...
false

结论:

1、默认在单例模式下ioc容器会调用方法创建对象放到ioc容器中,以后每次获取就是直接从容器中拿

2、多实例模式下,ioc容器启动并不会调用方法创建对象放入容器中,而是每次获取才调用方法创建对象,

​ 每次调用的都是新实例

三、@lazy-bean懒加载(针对单实例bean)

单实例bean:默认在容器启动的时候创建对象;

懒加载:容器启动不创建对象,第一次获取(使用)bean创建对象,并初始化

测试(无懒加载):

//    @Lazy
    @Bean("person")
    public Person person(){
        System.out.println("给容器中添加Person...");
        return new Person("张三",25);
    }

测试类:

    @Test
    public void test02(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
        System.out.println("ioc容器创建完成");
    }
}

结果:在容器创建前初始化bean

给容器中添加Person...
ioc容器创建完成

测试(有懒加载)结果:未初始化bean

ioc容器创建完成

测试(有懒加载,后来调用):

ioc容器创建完成
给容器中添加Person...
Person{name='张三', age=25}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值