zoukankan      html  css  js  c++  java
  • 重新学习Spring注解——ICO

    02、组件注册-@Configuration&@Bean给容器中注册组件

    03、组件注册-@ComponentScan-自动扫描组件&指定扫描规则

    04、组件注册-自定义TypeFilter指定过滤规则

    @Configuration  //告诉Spring这是一个配置类
    
    @ComponentScans(
            value = {
                    @ComponentScan(value = "com.learn", includeFilters = {
    /*						@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
                            @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/
                            @Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
                    }, useDefaultFilters = false)
            }
    )
    //@ComponentScan  value:指定要扫描的包
    //excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
    //includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
    //FilterType.ANNOTATION:按照注解
    //FilterType.ASSIGNABLE_TYPE:按照给定的类型;
    //FilterType.ASPECTJ:使用ASPECTJ表达式
    //FilterType.REGEX:使用正则指定
    //FilterType.CUSTOM:使用自定义规则
    public class MainConfig {
    
        //给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
        @Bean("person")
        public Person person01() {
            return new Person("lisi", 20);
        }
    
    }
    

      

    05、组件注册-@Scope-设置组件作用域

    06、组件注册-@Lazy-bean懒加载

    07、组件注册-@Conditional-按照条件注册bean

    08、组件注册-@Import-给容器中快速导入一个组件

    给容器中注入注解组件:

      1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)

      2)、@Bean[导入的第三方包里面的组件]

      3)、@Import [快速给容器中导入一个组件]

    09、组件注册-@Import-使用ImportSelector

    10、组件注册-@Import-使用ImportBeanDefinitionRegistrar

    11、组件注册-使用FactoryBean注册组件

    @Conditional({WindowsCondition.class})
    @Configuration
    @Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
    //@Import导入组件,id默认是组件的全类名
    public class MainConfig2 {
    
        //默认是单实例的
    
        /**
         * ConfigurableBeanFactory#SCOPE_PROTOTYPE
         *
         * @return
         * @Scope:调整作用域 prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
         * 每次获取的时候才会调用方法创建对象;
         * singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
         * 以后每次获取就是直接从容器(map.get())中拿,
         * request:同一次请求创建一个实例
         * session:同一个session创建一个实例
         * <p>
         * 懒加载:
         * 单实例bean:默认在容器启动的时候创建对象;
         * 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
         * @see ConfigurableBeanFactory#SCOPE_SINGLETON
         * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST  request
         * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION     sesssion
         */
    //	@Scope("prototype")
        @Lazy
        @Bean("person")
        public Person person() {
            System.out.println("给容器中添加Person....");
            return new Person("张三", 25);
        }
    
        /**
         * @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean
         * <p>
         * 如果系统是windows,给容器中注册("bill")
         * 如果是linux系统,给容器中注册("linus")
         */
    
        @Bean("bill")
        public Person person01() {
            return new Person("Bill Gates", 62);
        }
    
        @Conditional(LinuxCondition.class)
        @Bean("linus")
        public Person person02() {
            return new Person("linus", 48);
        }
    
        /**
         * 给容器中注册组件;
         * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
         * 2)、@Bean[导入的第三方包里面的组件]
         * 3)、@Import[快速给容器中导入一个组件]
         * 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
         * 2)、ImportSelector:返回需要导入的组件的全类名数组;
         * 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
         * 4)、使用Spring提供的 FactoryBean(工厂Bean);
         * 1)、默认获取到的是工厂bean调用getObject创建的对象
         * 2)、要获取工厂Bean本身,我们需要给id前面加一个&
         * &colorFactoryBean
         */
        @Bean
        public ColorFactoryBean colorFactoryBean() {
            return new ColorFactoryBean();
        }
    
    
    }
    

      


    12、生命周期-@Bean指定初始化和销毁方法
    13、生命周期-InitializingBean和DisposableBean
    14、生命周期-@PostConstruct&@PreDestroy
    15、生命周期-BeanPostProcessor-后置处理器
    16、生命周期-BeanPostProcessor原理
    17、生命周期-BeanPostProcessor在Spring底层的使用

    /**
     * bean的生命周期:
     * 		bean创建---初始化----销毁的过程
     * 容器管理bean的生命周期;
     * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
     * 
     * 构造(对象创建)
     * 		单实例:在容器启动的时候创建对象
     * 		多实例:在每次获取的时候创建对象
     * 
     * BeanPostProcessor.postProcessBeforeInitialization
     * 初始化:
     * 		对象创建完成,并赋值好,调用初始化方法。。。
     * BeanPostProcessor.postProcessAfterInitialization
     * 销毁:
     * 		单实例:容器关闭的时候
     * 		多实例:容器不会管理这个bean;容器不会调用销毁方法;
     * 
     * 
     * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
     * 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
     * 
     * BeanPostProcessor原理
     * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
     * initializeBean
     * {
     * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
     * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
     * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
     *}
     * 
     * 
     * 
     * 1)、指定初始化和销毁方法;
     * 		通过@Bean指定init-method和destroy-method;
     * 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
     * 				DisposableBean(定义销毁逻辑);
     * 3)、可以使用JSR250;
     * 		@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
     * 		@PreDestroy:在容器销毁bean之前通知我们进行清理工作
     * 4)、BeanPostProcessor【interface】:bean的后置处理器;
     * 		在bean初始化前后进行一些处理工作;
     * 		postProcessBeforeInitialization:在初始化之前工作
     * 		postProcessAfterInitialization:在初始化之后工作
     * 
     * Spring底层对 BeanPostProcessor 的使用;
     * 		bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;
     * 
     *
     */
    @ComponentScan("com.learn.bean")
    @Configuration
    public class MainConfigOfLifeCycle {
    	
    	//@Scope("prototype")
    	@Bean(initMethod="init",destroyMethod="detory")
    	public Car car(){
    		return new Car();
    	}
    
    }
    

      


    18、属性赋值-@Value赋值
    19、属性赋值-@PropertySource加载外部配置文件

    /**
     * Profile:
     * 		Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
     * 
     * 开发环境、测试环境、生产环境;
     * 数据源:(/A)(/B)(/C);
     * 
     * 
     * @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
     * 
     * 1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
     * 2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
     * 3)、没有标注环境标识的bean在,任何环境下都是加载的;
     */
    
    @PropertySource(value={"classpath:/dbconfig.properties"})
    @Configuration
    public class MainConfigOfProfile implements EmbeddedValueResolverAware{
    	
    	@Value("${db.user}")
    	private String user;
    	
    	private StringValueResolver valueResolver;
    	
    	private String  driverClass;
    	
    	@Profile("test")
    	@Bean
    	public Yellow yellow(){
    		return new Yellow();
    	}
    	
    	@Profile("test")
    	@Bean("testDataSource")
    	public DataSource dataSourceTest(@Value("${db.password}")String pwd) throws Exception{
    		ComboPooledDataSource dataSource = new ComboPooledDataSource();
    		dataSource.setUser(user);
    		dataSource.setPassword(pwd);
    		dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
    		dataSource.setDriverClass(driverClass);
    		return dataSource;
    	}
    	
    	
    	@Profile("dev")
    	@Bean("devDataSource")
    	public DataSource dataSourceDev(@Value("${db.password}")String pwd) throws Exception{
    		ComboPooledDataSource dataSource = new ComboPooledDataSource();
    		dataSource.setUser(user);
    		dataSource.setPassword(pwd);
    		dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm_crud");
    		dataSource.setDriverClass(driverClass);
    		return dataSource;
    	}
    	
    	@Profile("prod")
    	@Bean("prodDataSource")
    	public DataSource dataSourceProd(@Value("${db.password}")String pwd) throws Exception{
    		ComboPooledDataSource dataSource = new ComboPooledDataSource();
    		dataSource.setUser(user);
    		dataSource.setPassword(pwd);
    		dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/scw_0515");
    		
    		dataSource.setDriverClass(driverClass);
    		return dataSource;
    	}
    
    	@Override
    	public void setEmbeddedValueResolver(StringValueResolver resolver) {
    		this.valueResolver = resolver;
    		driverClass = valueResolver.resolveStringValue("${db.driverClass}");
    	}
    
    }
    

      


    20、自动装配-@Autowired&@Qualifier&@Primary

     21、自动装配-@Resource&@Inject

    22、自动装配-方法、构造器位置的自动装配

    23、自动装配-Aware注入Spring底层组件&原理

    /**
     * 自动装配;
     * 		Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;
     * 
     * 1)、@Autowired:自动注入:
     * 		1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
     * 		2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
     * 							applicationContext.getBean("bookDao")
     * 		3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
     * 		4)、自动装配默认一定要将属性赋值好,没有就会报错;
     * 			可以使用@Autowired(required=false);
     * 		5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;
     * 				也可以继续使用@Qualifier指定需要装配的bean的名字
     * 		BookService{
     * 			@Autowired
     * 			BookDao  bookDao;
     * 		}
     * 
     * 2)、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]
     * 		@Resource:
     * 			可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
     * 			没有能支持@Primary功能没有支持@Autowired(reqiured=false);
     * 		@Inject:
     * 			需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能;
     *  @Autowired:Spring定义的; @Resource、@Inject都是java规范
     * 	
     * AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能;		
     * 
     * 3)、 @Autowired:构造器,参数,方法,属性;都是从容器中获取参数组件的值
     * 		1)、[标注在方法位置]:@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配
     * 		2)、[标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取
     * 		3)、放在参数位置:
     * 
     * 4)、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);
     * 		自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;
     * 		把Spring底层一些组件注入到自定义的Bean中;
     * 		xxxAware:功能使用xxxProcessor;
     * 			ApplicationContextAware==》ApplicationContextAwareProcessor;
     * 	
     * 		
     *
     */
    @Configuration
    @ComponentScan({"com.learn.service","com.learn.dao",
    	"com.learn.controller","com.learn.bean"})
    public class MainConifgOfAutowired {
    	
    	@Primary
    	@Bean("bookDao2")
    	public BookDao bookDao(){
    		BookDao bookDao = new BookDao();
    		bookDao.setLable("2");
    		return bookDao;
    	}
    	
    	/**
    	 * @Bean标注的方法创建对象的时候,方法参数的值从容器中获取
    	 * @param car
    	 * @return
    	 */
    	@Bean
    	public Color color(Car car){
    		Color color = new Color();
    		color.setCar(car);
    		return color;
    	}
    
    }
    

    24、自动装配-@Profile环境搭建.avi

    25、自动装配-@Profile根据环境注册bean

    (1)使用命令行动态参数:见第19配置好不同数据源,在虚拟机位置添加:-Dspring.profiles.active=test

     (2) 代码的方式激活某种环境

        @Test
        public void test01(){
            /*
             * AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
             * 源码:
             * public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
             *  this();
             *  register(annotatedClasses);
             *  refresh();
             * }
             * 改造成无参构造:
             * register(annotatedClasses)与refresh()仍然需要执行
             * 
             */
            // 1、创建一个AnnotationConfigApplicationContext
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            // 2、设置激活的环境 ;源码(可以同时激活多种环境):public void setActiveProfiles(String... profiles)
            context.getEnvironment().setActiveProfiles("dev");
            // 3、设置主配置类
            context.register(MainConfigOfAutowired.class);
            // 4、刷新容器
            context.refresh();
        }

    26、IOC-小结

  • 相关阅读:
    topcoder srm 320 div1
    topcoder srm 325 div1
    topcoder srm 330 div1
    topcoder srm 335 div1
    topcoder srm 340 div1
    topcoder srm 300 div1
    topcoder srm 305 div1
    topcoder srm 310 div1
    topcoder srm 315 div1
    如何统计iOS产品不同渠道的下载量?
  • 原文地址:https://www.cnblogs.com/gzhcsu/p/11415782.html
Copyright © 2011-2022 走看看