zoukankan      html  css  js  c++  java
  • 1spring注解:@Configuration,@Bean,@ComponentScan(),@Scope

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物,这么做有两个缺点:
    1、如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大;如果按需求分开.xml文件,那么.xml文件又会非常多。总之这将导致配置文件的可读性与可维护性变得很低。
    2、在开发中在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率。
    为了解决这两个问题,Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密结合,既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。

    所有的注解都是在一个工程中进行演示、后面不懂得可以参考前面的随笔!

    开始注解的代码编程:

    1.工程准备
    Person.class
    public class Person {    
         private String name;
         private int age;
    ...
    }
    配置类:
    Config.class
    //配置类 === 配置文件xxx.xml
    //@Configuration是告诉Spring这是一个配置类
    @Configuration
    public class Config {
         
             //给容器注册一个bean,相当于配置文件的 <bean></bean>
             //类型默认是返回的类型
             //id默认是方法名
         @Bean("per")
         public Person person(){
               return new Person("MrChengs",20);
         }
    }

     测试:

               ApplicationContext app = new  AnnotationConfigApplicationContext(Config.class);
               Person p =app.getBean(Person.class);
               System.out.println(p);
    Person [name=MrChengs, age=20]
     
     
    1.@Configuration
    告诉sprin该类是一个配置类
    所谓的配置类相当于我们所写的xxx.xml配置文件
     
    2.@Bean
    给容器中注入一个Bean,相当于<bean></bean>进行实例化一个bean
     
    属性:
    默认value可以不写

     

     

     3.@ComponentScan()

     等同于:<context:component-scan  base-package=""></context:component-scan>

    新建四个类,分别使用:@Repository,@Service,@Controller三个注解

    @Repository
    public class CustomerDao {
    }
    @Service
    public class CustomerService {
    }
    @Controller
    public class CustomerConteoller {
    }

     在Config.class类中

    @Configuration
    @ComponentScan(value="coom.MrChengs.config",excludeFilters={
               @Filter(type=FilterType.ANNOTATION,classes={Repository.class})})
    public class Config {
         
         @Bean("per")
         public Person person(){
               return new Person("MrChengs",20);
         }
    }
    @ComponentScan:

     value :指定需要扫描的包

     excludeFilters :指定扫描的适合排除那些包

        Filter[] excludeFilters() default {};
             FilterType type() default FilterType.ANNOTATION;
                  Class<?>[] classes() default {};

     includeFilters: 指定扫描的时候只包含那些包

           在使用的时候需要添加:useDefaultFilters=false属性

           其余属性和excludeFilters类似

     @Test
         public void test(){
               ApplicationContext app = new  AnnotationConfigApplicationContext(Config.class);
               //获取bean的name
           String [] names
    = app.getBeanDefinitionNames(); for(String name : names){ System.out.println(name); } }
    config
    customerConteoller
    customerService
    per

    关于@Filter的使用:

    1.type=FilterType.ANNOTATION: 是根据注解的规则
    2.type=FilterType.ASSIGNABLE_TYPE:按照给定的类型
      @Filter(type=FilterType.ASSIGNABLE_TYPE,classes=CustomerService.class
    3.type=FilterType.ASPECTJ:使用aspectj表达式
    4.type=FilterType.REGEX:使用正则表达式
    5.type=FilterTyoe.CUSTOM:自定义规则

     使用5进行测试:

    @ComponentScan(value="coom.MrChengs.config",includeFilters={
               @Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class}),       
    },useDefaultFilters=false)
    public class MyTypeFilter implements TypeFilter{
         //MetadataReader:读取到当前正在扫描的包信息
         //MetadataReaderFactory:可以获取到其他类的任何信息
         public boolean match(MetadataReader arg0,  MetadataReaderFactory arg1) throws IOException {
               //获取当前类的注解信息
               AnnotationMetadata annotationMetadata  =arg0.getAnnotationMetadata();
               //获取当前正在扫描类的信息
               ClassMetadata classMetadata =  arg0.getClassMetadata();
               //获取当前类的资源(路径,url...)
               Resource resource =  arg0.getResource();
               
                //获取类的全类名
                //扫描到的类
               String className = classMetadata.getClassName();
               System.out.println("--->" + className);
               return false;
         }
    }
    在测试打印的时候
    这些都是className中打印出来的
    扫描到的类
    --->coom.MrChengs.config.conteoller.CustomerConteoller
    --->coom.MrChengs.config.dao.CustomerDao
    --->coom.MrChengs.config.MyTypeFilter
    --->coom.MrChengs.config.service.CustomerService
    return true的时候
    当然我们可以进行系统的判断进行放行
    config
    customerConteoller
    customerDao
    myTypeFilter
    customerService
    可以把所有的@ComponentScan都写在里面
    @ComponentScans(value={@ComponentScan(value="coom.MrChengs.config",excludeFilters={
               @Filter(type=FilterType.ANNOTATION,classes={Repository.class})})}
    )

    4.@Scope  调整作用域

    Config2.java

    @Configuration
    public class Config2 {
         
         @Bean("per")
         public Person person(){
               return new Person("MrChengs",20);
         }
    }

    测试

       @Test
         public void test2(){
               ApplicationContext app = new  AnnotationConfigApplicationContext(Config2.class);
               String [] names = app.getBeanDefinitionNames();
               for(String name : names){
                    System.out.println(name);
               }
               Person p  = (Person) app.getBean("per");
               Person p1  = (Person) app.getBean("per");
               System.out.println(p == p1);
               
         }
    config2
    per
    true

    说明默认是单实例的,只实例化一个bean

    @Scope

    * @see ConfigurableBeanFactory#SCOPE_PROTOTYPE   
    * @see ConfigurableBeanFactory#SCOPE_SINGLETON
    * @see  org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
    * @see  org.springframework.web.context.WebApplicationContext#SCOPE_SESSION
         //prototype  多实例的    在IOC容器创建之后获取对象才开始创建,获取一次创建一次
         //singleton  单例的   IOC容器启动的时候就会调用对象放到IOC容器中,多次获取也是只获取同一个
         //request   同一次请求
         //session   同一个session
    @Configuration
    public class Config2 {
         //prototype  多实例的
         //singleton  单例的
         //request
         //session
         @Scope(value="prototype")
         @Bean("per")
         public Person person(){
               return new Person("MrChengs",20);
         }
    }
    config2
    per
    false

    多实例情况下,获取一次则创建一个实例

  • 相关阅读:
    Flask的部署
    server 08 R2 NBL 报错:RPC 服务器在指定计算机上不可用
    Exchange 2010 打补丁的顺序
    批量创建域账号
    Exchange 正版化 授权
    邮件本地备份策略原则
    TMG 模拟公司网络架构要点
    webservice 测试地址
    PYDay10&11&12&13-常用模块:time|datetime|os|sys|pickle|json|xml|shutil|logging|paramiko、configparser、字符串格式化、py自动全局变量、生成器迭代器
    Python 编程要求
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/10108603.html
Copyright © 2011-2022 走看看