Spring注解使用【1】@Configuration@Bean@ComponentScan@scope@Lazy

7 篇文章 0 订阅
4 篇文章 0 订阅

Spring注解驱动开发【1】
@Configuration@Bean@ComponentScan@scope@Lazy

github源码下载:https://github.com/LuckyShawn/spring-annotation

一、先回顾用配置文件xml是如何注入一个bean并获取的。

  1. 创建一个Person类
package com.shawn.bean;

public class Person {
   private String name;
   private Integer age;
   //省略get、set、toString方法
  1. 创建Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="person" class="bean.Person"  scope="prototype" >
   	<property name="age" value="20"></property>
   	<property name="name" value="zhangsan"></property>
   </bean>
</beans>
  1. 测试类
//利用配置文件的方式
    @Test
    public void test01(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        Person person = (Person) ac.getBean("person");
        System.out.println(person);
    }
结果:Person [name=zhangsan, age=20]

二、用注解@Configuration @Bean获取bean

  1. Config类 配置类==配置文件
@Configuration	//告诉Spring这是一个配置类
public class Config01 {

	//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    @Bean("person") 
    public Person person(){
        return new Person("lise",20);
    }
}
  1. 测试
//配置类的方式
    @Test
    public void test02(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(Config01.class);
        Person person = (Person) ac.getBean("person");
        System.out.println(person);
    }
结果:Person [name=zhangsan, age=20]
//与配置文件结果一致

三、@ComponentScans自动扫描组件

包扫描、只要标注了@Controller、@Service、@Repository,@Component

  1. 编写主配置类
@Configuration //告诉Spring这是一个配置类  配置类==配置文件
//组件扫描 includeFilters:只需要哪些bean, useDefaultFilters = false 关闭默认过滤器
//包扫描、只要标注了@Controller、@Service、@Repository,@Component
@ComponentScans(
        value = {
                @ComponentScan(value="com.shawn",includeFilters = {
						@ComponentScan.Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
						@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class})
                },useDefaultFilters = false)
        }
)
//@ComponentScan  value:指定要扫描的包
//excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
//includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
//FilterType.ANNOTATION:按照注解
//FilterType.ASSIGNABLE_TYPE:按照给定的类型;
//FilterType.ASPECTJ:使用ASPECTJ表达式
//FilterType.REGEX:使用正则指定
//FilterType.CUSTOM:使用自定义规则
public class Config01 {

    @Bean("person") //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
    public Person person(){
        return new Person("lise",20);
    }
}

  1. 新建用于测试的dao,service,controller
    在这里插入图片描述
@Repository
public class BookDao {
}
@Service
public class BookService {
}
@Controller
public class BookController {
}

  1. 测试
@Test
    public void test03(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config01.class);
        //获取所有标注的bean
        String[] definitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : definitionNames) {
            System.out.println(name);
        }
    }

结果:
在这里插入图片描述
因为在扫描的时候我们注解@ComponentScan只需要BookService和Controller,所以没有bookDao这个bean

附:也可以使用@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})自定义规则进行过滤

public class MyTypeFilter implements TypeFilter {
	/**
	 * metadataReader:读取到的当前正在扫描的类的信息
	 * metadataReaderFactory:可以获取到其他任何类信息的
	 */
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		// TODO Auto-generated method stub
		//获取当前类注解的信息
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		//获取当前正在扫描的类的类信息
		ClassMetadata classMetadata = metadataReader.getClassMetadata();
		//获取当前类资源(类的路径)
		Resource resource = metadataReader.getResource();

		String className = classMetadata.getClassName();
		System.out.println("--->"+className);
		if(className.contains("controller")){
			return true;
		}
		return false;
	}

四、@scope @Lazy

  1. 创建config02
@Configuration
public class Config02 {


    //默认是单实例的
    /**
     * @see ConfigurableBeanFactory#SCOPE_PROTOTYPE     prototype
     * @see ConfigurableBeanFactory#SCOPE_SINGLETON     singleton
     * @see //org.springframework.web.context.WebApplicationContext SCOPE_REQUEST
     * @see //org.springframework.web.context.WebApplicationContext SCOPE_SESSION
     * @Scope:调整作用域
     * prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
     * 					每次获取的时候才会调用方法创建对象;
     * singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
     * 			以后每次获取就是直接从容器(map.get())中拿,
     *
     * 	Web环境下:
     * request:同一次请求创建一个实例
     * session:同一个session创建一个实例
     *
     * 懒加载:
     * 		单实例bean:默认在容器启动的时候创建对象;
     * 		懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
     *
     */
   //@Lazy
    @Scope("prototype")
    @Bean("person")
    public Person person(){
        return new Person("jack",18);
    }
}
  1. 测试
 //测试组件作用域
    @Test
    public void test04(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config02.class);
        String [] names = applicationContext.getBeanDefinitionNames();
        for(String name : names){
            System.out.println(name);
        }

        Object person01 = applicationContext.getBean("person");
        Object person02 = applicationContext.getBean("person");
        System.out.println(person01 == person02);
        //true 返回的是同一个实例

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值