zoukankan      html  css  js  c++  java
  • Spring5源码深度解析(一)之理解Configuration注解

    代码地址:https://github.com/showkawa/spring-annotation/tree/master/src/main/java/com/brian

    1.Spring体系结构

    1.1、Spring Core:主要组件是BeanFactory,创建JavaBean的工厂,使用控制反转(IOC) 模式  将应用程序的配置和依赖性规范与实际的应用程序代码分开。

    1.2、Spring AOP:集成了面向切面的编程功能(AOP把一个业务流程分成几部分,例如权限检查、业务处理、日志记录,每个部分单独处理,然后把它们组装成完整的业务流程。每个部分被称为切面),

     可以将声明性事物管理集成到应用程序中。

    1.3、Spring Cntext:一个核心配置文件,为Spring框架提供上下文信息。

    1.4、Spring Do:Spring操作数据库的模块。

    1.5、Spring ORM:Spring集成了各种orm(object relationship mapping 对象关系映射)框架的模块,集成mybatis

    1.6、Spring Web集成各种优秀的web层框架的模块(Struts、Springmvc)

    1.7、Spring web MVC:Spring web层框架

     2.Configuration注解分析内容(@Configuration,@ComponentScan,@Scope,@Lazy)

    2.1 @Configuration

     @Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

    2.1.1 @Configuration标注在类上,相当于把该类作为spring的xml配置文件中的<beans>,作用为:配置spring容器(应用上下文)

    @Configuration
    public class MainConfigOfLifeCycle { }


    //测试方法

    public static void main(String[] args) {
    ApplicationContext acac =
    new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
    System.out.println("ioc容器创建成功");

    //关闭ioc容器
    ((AnnotationConfigApplicationContext) acac).close();
    }
     

    相当于spring的xml配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
        xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-5.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-5.0.xsd
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-5.0.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-5.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-5.0.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-5.0.xsd
            http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-5.0.xsd" default-lazy-init="false">
    
    
    </beans>

    2.2 @ComponentScan用法 

     ComponentScan字面意思就是组件扫描,就是根据定义的扫描路径,把符合扫描规则的类装配到spring容器中

      2.2.1 ComponentScan参数说明

    /*
    * @ComponentScan
    * value:只当于扫描的的包
    * excludeFilters = 指定扫描的时候按照什么规则排除哪些组件
    * includeFilters = 指定扫描的时候只需要包含哪些组件
    * Filter.ANNOTATION:按照注解
    * Filter.ASSIGNABLE_TYPE: 按照给定的类型
    * */

    FilterType 有五种类型

    ANNOTATION:注解类型

    ASSIGNABLE_TYPE:ANNOTATION:指定的类型

    ASPECTJ:按照Aspectj的表达式,基本上不会用到

    REGEX:按照正则表达式

    CUSTOM:自定义规则

    package com.brian.config;
    
    import com.brian.bean.Alan;
    import com.brian.bean.Brian;
    import com.brian.bean.BrianBeanFactory;
    import com.brian.bean.Person;
    import com.brian.condition.BrianCondition;
    import com.brian.condition.BrianSelector;
    import com.brian.service.BookService;
    import org.springframework.context.annotation.*;
    import org.springframework.stereotype.Controller;
    
    @Configuration //告诉spring这是一个配置类
    /*
    * @ComponentScan
    *   value:只当于扫描的的包
    *   excludeFilters = 指定扫描的时候按照什么规则排除哪些组件
    *   includeFilters = 指定扫描的时候只需要包含哪些组件
    *   Filter.ANNOTATION:按照注解
    *   Filter.ASSIGNABLE_TYPE: 按照给定的类型
    * */
    
    @ComponentScans(value = {
            @ComponentScan(value = "com.brian",includeFilters = {
    //                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
    //                @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes = {BookService.class}),
                    @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {BrianTypeFilter.class})
            },useDefaultFilters = false)
    })
    @Import({Brian.class,Alan.class,BrianSelector.class})
    public class MainConfig {
    
        @Bean("person") //给容器中注册一个Bean;类型为返回值的类型;id默认是方法名作为id
        public Person person(){
            return new Person("Alan",18);
        }
    
    
        /*
        * @Conditional() 按照条件注册
        *
        * */
        @Conditional({BrianCondition.class})
        @Bean("person01")
        public Person person01() {
            return new Person("Brian",17);
        }
    
        @Conditional({BrianCondition.class})
        @Bean("person02")
        public Person person02() {
            return new Person("wenTao",19);
        }
    
        /*
        *
        *给容器中注册组件
        * 1,包扫描+ 组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的方法]
        * 2, @Bean [导入的第三方包里面的组件]
        * 3,@Import [快速的给容器导入一个组件]
        *       1.@Import(要导入的组件class)
        *       2.ImportSelector:返回需要导入的组件的全类名数组
        *       3.ImportBeanDefinitionRegistrar: 手动注册bean到容器
        *  4. 使用Spring提供的FactoryBean
        * */
        @Bean
        public BrianBeanFactory brianBeanFactory() {
            return new BrianBeanFactory();
        }
    
    }

    2.3 @Scope

    默认情况Spring容器是单例的

    singleton单例模式:全局有且仅有一个实例。

    prototype原型模式:每次获取Bean的时候都会有一个新的实例。

    request

    request表示针对每次请求都会产生一个新的Bean对象,并且该Bean对象仅在当前Http请求内有效。

    session

    session作用域表示煤气请求都会产生一个新的Bean对象,并且该Bean仅在当前Http session内有效。

    测试@Scopeprototype原型模式

    Configuration配置类

    @Configuration
    @ComponentScan("com.brian.bean")
    public class MainConfigOfLifeCycle {
        @Scope("prototype")
        @Bean(initMethod = "init", destroyMethod = "destroy")
        public Alan getAlan () {
            return new Alan();
        }
    }

    测试类

    public class MainTest {
        public static void main(String[] args) {
             /*ApplicationContext acac =
                     new AnnotationConfigApplicationContext(MainConfig.class);*/
             ApplicationContext acac =
                     new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
            System.out.println("ioc容器创建成功");
            Alan alan1 =  acac.getBean(Alan.class);
            Alan alan2 =  acac.getBean(Alan.class);
            System.out.println("比较两个Alan实例: " + (alan1 == alan2));
    
            //关闭ioc容器
            ((AnnotationConfigApplicationContext) acac).close();
        }
    }

    2.4 @Lazy

    Lazy表示为懒加载,当真正需要引用获取的时候才会被加载

    True 表示为懒加载 false表示为在IOC容器加载的时候被创建。

    测试@Lazy(false)饿汉模式加载

    Configuration配置类

    @Configuration
    @ComponentScan("com.brian.bean")
    public class MainConfigOfLifeCycle {
        //@Scope("prototype")
        @Lazy(false)
        @Bean(initMethod = "init", destroyMethod = "destroy")
        public Alan getAlan () {
            return new Alan();
        }
    
    
    }

    测试类

    public class MainTest {
        public static void main(String[] args) {
             /*ApplicationContext acac =
                     new AnnotationConfigApplicationContext(MainConfig.class);*/
             ApplicationContext acac =
                     new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
            System.out.println("ioc容器创建成功");
          //  Alan alan1 =  acac.getBean(Alan.class);
           // Alan alan2 =  acac.getBean(Alan.class);
            //System.out.println("比较两个Alan实例: " + (alan1 == alan2));
    
            //关闭ioc容器
            ((AnnotationConfigApplicationContext) acac).close();
        }
    }

     看下结果会发现在饿汉模式下,即使没用使用AnnotationConfigApplicationContext.getBean()获取对象,对象也被加载进了IOC容器

    测试@Lazy默认懒加载

     Configuration配置类

    @Configuration
    @ComponentScan("com.brian.bean")
    public class MainConfigOfLifeCycle {
        //@Scope("prototype")
        @Lazy
        @Bean(initMethod = "init", destroyMethod = "destroy")
        public Alan getAlan () {
            return new Alan();
        }
    
    
    }

    测试类保持不表

    测试结果中,没有输出Alan这个对象创建和销毁的打印信息

  • 相关阅读:
    21世纪网络创业新生代中国海归的传承与开创圆桌论坛实录_网络营销_网赚猫 及时更新网络赚钱_网赚项目_兼职_网络营销等相关网赚资讯
    知方可补不足~利用LogParser将IIS日志插入到数据库
    WebApi系列~自主宿主HttpSelfHost的实现
    我心中的核心组件(可插拔的AOP)~第十五回 我的日志组件Logger.Core(策略,模版方法,工厂,单例等模式的使用)
    爱上MVC系列~前端验证与后端数据有效性验证
    第九回 Microsoft.Practices.Unity.Interception实现基于数据集的缓存(针对六,七,八讲的具体概念和配置的解说)
    struts2第一个程序的详解(配图)
    JavaScript中的对象(一)
    SqlServer操作远程数据库
    [leetcode]Binary Tree Inorder Traversal
  • 原文地址:https://www.cnblogs.com/hlkawa/p/11085020.html
Copyright © 2011-2022 走看看