Spring 第二 随笔记

【spring除了XML配置外,还有注解类配置,这个就主要讲注解类配置】

第一部分 : 往容器中添加组件的几种方式。。

package com.abc.config;

import com.abc.condition.LinuxCondition;
import com.abc.condition.WindowsCondition;
import com.abc.domain.Color;
import com.abc.domain.Person;
import com.abc.domain.Student;
import com.abc.myTypeFilter;
import org.springframework.context.annotation.*;
import org.springframework.context.annotation.ComponentScan.Filter;
/**
 * excludeFilters 排除过滤容器的对象
 * includeFilters 包含容器对象
 */
/**
 * 一个 ComponentScans 【这个带 s 哦】 里面有个属性为 value,value是个集合,可以有多个ComponentScan属性,然后再......
 *
 * 【value = "com.abc" ;它的作用是扫描这个包下的,但是是否加入包含还是排斥,需要后面的代码了】
 *
 * excludeFilters:不包含过滤-->即 Filter注解上的都不加载进容器
 * includeFilters: 包含过滤---->即 Filter注解上的才会加载进容器
 * FilterType.ANNOTATION 表示注解类型的  即例如 Controller.class,Component.class ,Service.class 等等类型
 * FilterType.ASSIGNABLE_TYPE 表示指定类型的  即如我自己写的Student类型【Student.class】 StudentController类型【StudentController.class】等等
 * FilterType.ASPECTJ 表示Aspect类型的  ,几乎不用
 * FilterType.REGEX   表示满足正则表达式的,
 * FilterType.CUSTOM  表示使用自定义规则   创建实现TypeFilter实现类,若返回true,加入容器,返回false,不让加入容器
 */
/*@ComponentScans(value = {
        @ComponentScan(value = "com.abc",excludeFilters = {
                @Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
        })
})*/
/*@ComponentScans(value = {
        @ComponentScan(value = "com.abc",includeFilters = {
                @Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Student.class})
        })
})*/
@Configuration
@ComponentScans(value = {
        @ComponentScan(value = "com.abc",excludeFilters = {
                @Filter(type = FilterType.CUSTOM,classes = {myTypeFilter.class})
        },useDefaultFilters = false)
})
/**
 * 【使用第三种方式给容器导入组件使用---->>Import】
 */
@Import(Color.class)
public class myConfig {
    /**
     * @Scope作用是否是单例
     *
     * singleton:  单例的(默认值)Ioc容器启动会调用方法创建对象放到Ioc容器中,以后调用直接从容器中拿
     * prototype:  多实例的,Ioc容器并不会去调用方法创建对象放在容器中
     * request:     同意一次请求创建一个实例
     * session:     同一个Session会话
     */
    @Scope("singleton")
    @Bean
    public Student student(){
        Student student = new Student("张三", "男", 23);
        return student;
    }


    /**
     * @Conditional
     * @return
     */

    @Conditional(WindowsCondition.class)
    @Bean("bill")
    public Person person01(){
        return new Person("李四",24);
    }


    @Conditional(LinuxCondition.class)
    @Bean("linux")
    public Person person02(){
        return new Person("王五",25);
    }

    /**
     * 使用第三种方式给容器导入组件使用---->>Import
     * 1.  在配置类上加 Import(类的class对象)这是个数组,可以多个
     * 2.  还可以实现 【ImportSelector】 接口,然后在实现类添加需要加入容器的组件,注意加入的是  类的全限定名
     * 3.  还可以实现ImportBeanDefinitionRegistrar 接口:手动注册
     */


}

 【使用自定义规则】

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

public class myTypeFilter implements TypeFilter {
    /**
     * metadataReader : 读取到的当前类扫描到的信息
     * metadataReaderFactory: 可以获取到其他任何类型的
     */
    @Override
    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();
    /*    if (className.contains("er")){
            System.out.println(" *********************"+className);
            return true;
        }*/
        return false;
    }
}

【小知识 0.1】

            @Scope()// 1 .默认是 singleton 但是可以改变使用 prototype变成多实例的

                         singleton: 单例的(默认值)Ioc容器启动会调用方法创建对象放到Ioc容器中,以后调用直接从容器中拿

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

                         prototype: 多实例的情况,Ioc容器启动并不会去调用方法创建对象放在容器中,而是每次获取的时候才会调用方法新创建对象

                                        每次调用都会新的 new一个

    @Scope()//  1 .默认是 singleton  但是可以改变使用 prototype变成多实例的  
@Bean
public Person person(){ return new Person("张三",23); }

 

 

 

一:往容器中加组件的七种方式

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

  1.注解@Bean

  2.注解@Condition ------加条件

  

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class LinuxCondition implements Condition {
    /**
     * ConditionContext :上下文信息
     * AnnotatedTypeMetadata:获取当前类注解信息
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //1 获取到Ioc使用的BeanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2 获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //3 获取环境信息
        Environment environment = context.getEnvironment();
        //4 获取到Bean 定义的注册类
        BeanDefinitionRegistry registry = context.getRegistry();

        String property = environment.getProperty("os.name");
        if (property.contains("linux")){
            return true;
        }

        return false;
    }
}

 

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class WindowsCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //1 获取到Ioc使用的BeanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2 获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //3 获取环境信息
        Environment environment = context.getEnvironment();
        //4 获取到Bean 定义的注册类
        BeanDefinitionRegistry registry = context.getRegistry();

        String property = environment.getProperty("os.name");
        if (property.contains("Windows")){
            return true;
        }
        return false;
    }
}

 

 

3.注解@Import  【集合:可以多个】

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(Color.class,Person.class)  //导入组件,id默认是组件的全类名
public class MainConfigration {
    
}

 

  4.实现 ImportSelector 接口

//自定义组件
public class MyImportSelector implements ImportSelector {
    //返回值就是导入组件的全类名
    //AnnotationMetadata:当前标注@Import注解类的所有信息,还能获取其他注解
     //                                        比如:   //@Configuration
                                                        //@Import({Color.class, Person.class,MyImportSelector.class})
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {

        return new String[]{"aynu.test3.Color","aynu.test2.Person"};//方法不能返回null
    }
}

 

  5.实现 ImportBeanDefinitionRegistrar  接口

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * AnnotationMetadata: 当前类大注解信息
     * BeanDefinitionRegistry: BeanDefinition注册类
     *           把所有需要添加到容器的中的Bean: 调用
     *           BeanDefinitionRegistry.registryBeanDefinition手工注册进来
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean red = registry.containsBeanDefinition("red");
        boolean blud = registry.containsBeanDefinition("blud");
        //如果容器中有 【red】 和【blud】两个组件,就把下面的组件加入容器
        if (red && blud){
            RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
            //注册一个Bean,并且制定bean名称
            registry.registerBeanDefinition("raidBow",beanDefinition);
        }
    }
}

   6.实现 FactoryBean<> 接口

import com.abc.domain.Color;
import org.springframework.beans.factory.FactoryBean;

public class myFactoryBean implements FactoryBean<Color> {

    //返回一个对象,这个对象会被添加到容器中
    @Override
    public Color getObject() throws Exception {
        return new Color();
    }
    //从容器拿出组件时的类型
    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }
    //报存是否为单例 ,如果是true 就是单例,返回false就是非单例
    @Override
    public boolean isSingleton() {
        return false;
    }
}

 第二部分 : bean的生命周期

    第一种方式:1)。指定初始化和销毁的方法指定init-method destroy-method

  

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * 构造 ;
 *    单实例:容器启动的时候创建对象
 *    多实例:在每次获取的时候创建对象
* 初始化:
* 对象创建完成,并赋值好,调用初始化方法
* 销毁:
* 单实例:容器关闭的时候
* 多实例:容器不会管理这个bean:容器不会调用销毁 * 1)。指定初始化和销毁的方法 * 指定init-method 和 destroy-method *
*/ public class IocTest { @Test public void fun1(){ AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MianConfigLeftCycle.class); System.out.println("容器创建完成"); //关闭容器 ac.close(); } }

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MianConfigLeftCycle {
    //如果此处加上注解 @prototype 这就是多实例化,就会在调用的时候才创建
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Car car(){
        return new Car();
    }
}


public class Car {
    public Car(){
        System.out.println("生成 Car 了.......");
    }
    public void init(){
        System.out.println("初始化完成......");
    }
    public void destory(){
        System.out.println("销毁完成.....");
    }
}

 

 

第二种方式:通过让Bean实现 InitializingBean(定义初始化逻辑),

                      DisposableBean(定义销毁逻辑)

@Component
public class Car implements InitializingBean, DisposableBean {
    public Car(){
        System.out.println("生成 Car 了.......");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("销毁完成.......");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("创建完成..........");
    }
}


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;


@Configuration
@ComponentScan("com.bcd")
public class MianConfigLeftCycle {

    @Bean
    public Car car(){
        return new Car();
    }
}

第三种:JSR250装饰, 

              @PostConstruct:在Bean 创建完成并且属性赋值完成:来执行初始化方法

              @PreDestory:       在容器销毁Bean之前通知我们进行清理工作

public class IocTest {
    @Test
    public void fun1(){
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MianConfigLeftCycle.class);
        System.out.println("容器创建完成");
        //关闭容器
        ac.close();
    }
}
//打印结果
生成 Car 了.......
销毁完成..........
dog  初始化完成
Dog @PostConstruct 初始化完成
容器创建完成
Dog @PreDestroy 销毁完成
初始化完成.......】】】】】】】


import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class Dog {
    public Dog(){
        System.out.println("dog  初始化完成");
    }
    //对象创建并赋值之后调用
    @PostConstruct
    public void init(){
        System.out.println("Dog @PostConstruct 初始化完成");
    }
    //销毁之前调用
    @PreDestroy
    public void destory(){
        System.out.println("Dog @PreDestroy 销毁完成");
    }
}


@Configuration
@ComponentScan("com.bcd")
public class MianConfigLeftCycle {

    @Bean
    public Car car(){
        return new Car();
    }
}

 

第四种:BeanPostProcessor :bean的后置处理器

              在Bean初始化前后进行一些处理工作

      postProcessBeforeInitialization :在初始化调用之前调用  init
      postProcessAfterInitialization : 在初始化调用之后调用  init
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component//加入容器
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization"+beanName+"=="+bean);
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization"+beanName+"=="+bean);
        return bean;
    }
}

【读读源码】
/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

/**
 * Factory hook that allows for custom modification of new bean instances,
 * e.g. checking for marker interfaces or wrapping them with proxies.
 *
 * <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
 * bean definitions and apply them to any beans subsequently created.
 * Plain bean factories allow for programmatic registration of post-processors,
 * applying to all beans created through this factory.
 *
 * <p>Typically, post-processors that populate beans via marker interfaces
 * or the like will implement {@link #postProcessBeforeInitialization},
 * while post-processors that wrap beans with proxies will normally
 * implement {@link #postProcessAfterInitialization}.
 *
 * @author Juergen Hoeller
 * @since 10.10.2003
 * @see InstantiationAwareBeanPostProcessor
 * @see DestructionAwareBeanPostProcessor
 * @see ConfigurableBeanFactory#addBeanPostProcessor
 * @see BeanFactoryPostProcessor
 */
public interface BeanPostProcessor {

    /**
     * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * <p>The default implementation returns the given {@code bean} as-is.
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one;
     * if {@code null}, no subsequent BeanPostProcessors will be invoked
     * @throws org.springframework.beans.BeansException in case of errors
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     */
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
     * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
     * or a custom init-method). The bean will already be populated with property values.
     * The returned bean instance may be a wrapper around the original.
     * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
     * instance and the objects created by the FactoryBean (as of Spring 2.0). The
     * post-processor can decide whether to apply to either the FactoryBean or created
     * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
     * <p>This callback will also be invoked after a short-circuiting triggered by a
     * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
     * in contrast to all other BeanPostProcessor callbacks.
     * <p>The default implementation returns the given {@code bean} as-is.
     * @param bean the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one;
     * if {@code null}, no subsequent BeanPostProcessors will be invoked
     * @throws org.springframework.beans.BeansException in case of errors
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
     * @see org.springframework.beans.factory.FactoryBean
     */
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}


打印结果
postProcessBeforeInitializationmianConfigLeftCycle==com.bcd.MianConfigLeftCycle$$EnhancerBySpringCGLIB$$f7ef0e67@75f32542
postProcessAfterInitializationmianConfigLeftCycle==com.bcd.MianConfigLeftCycle$$EnhancerBySpringCGLIB$$f7ef0e67@75f32542
生成 Car 了.......
postProcessBeforeInitializationcar==com.bcd.Car@29176cc1
初始化完成..........
postProcessAfterInitializationcar==com.bcd.Car@29176cc1
dog  初始化完成
postProcessBeforeInitializationdog==com.bcd.Dog@77167fb7
Dog @PostConstruct 初始化完成
postProcessAfterInitializationdog==com.bcd.Dog@77167fb7
容器创建完成
Dog @PreDestroy 销毁完成
销毁完成.......

第三部分:属性赋值

  第一种:使用@Value赋值

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestpropertyValues {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MianConfigpropertyValues.class);
    @Test
    public void fun1(){
        System.out.println("容器创建完成");
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
       Object person = ac.getBean("person");
        System.out.println(person);
        //关闭容器
      //  ac.close();
    }
}
package com.cdf;

import org.springframework.beans.factory.annotation.Value;

public class Person {
    //使用@Value赋值
    /**
     * 1 .基本类型
     * 2 。可以写SPEL;#{}
     * 3 .可以用${} , 从配置文件获取
     */
    @Value("张三")
    private String name;
    //@Value("23")
    private Integer age;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Person() {
    }
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
//使用@PropertySource读取外部配置文件中的K/V保存到运行的环境变量中:
//加载完外部的配置使用${}获取

/**
 *  ConfigurableEnvironment environment = ac.getEnvironment();
 *  String age = environment.getProperty("age");
 *  用这个方法也是可以的,默认都加载到环境变量
 */
@PropertySource(value = {"class:/person.properties"})
@Configuration
public class MianConfigpropertyValues {
    @Bean
    public Person person(){
        return new Person();
    }
}

 第二种:用@PropertySource读取外部配置文件中的K/V保存到运行的环境中;加载完外部的配置文件以后

               使用${}去除配置文件的值

 

第四部分:自动装配

    Spring利用依赖注入(DI)完成对IOC容器各个组件的赋值

  第一种:使用Autoware

/**
* 1)自动装配Autowared
* 1. 默认优先按照类型去容器中找对应的组件:applicationContext.getBean(Person.class);
* 2.如果找到多个类型相同的组件,再将属性的名称作为组件的Id去容器查找
* applicationContext.getBean("personDao");
* 3.使用 @Qualifier("persondao");,可以明确制定去组件ID
* 4.只要使用自动装配,就一定要将属性赋值好,如果容器没有就会报错
* 5. @Primary ,让Spring进行自动装配的时候,默认首选的是Bean
* 也可以继续使用 @Qualifier指定需要装配的Bean的名字
* 【注意】
* Autowared(required=false) 指定为false 就不必须了会默认赋值为null
*/
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 *   1)自动装配Autowared
 *       1. 默认优先按照类型去容器中找对应的组件:applicationContext.getBean(Person.class);
 *       2.如果找到多个类型相同的组件,再将属性的名称作为组件的Id去容器查找
 *                                       applicationContext.getBean("personDao");
 *       3.使用 @Qualifier("persondao");,可以明确制定去组件ID
 *       4.只要使用自动装配,就一定要将属性赋值好,如果容器没有就会报错
 *       5. @Primary ,让Spring进行自动装配的时候,默认首选的是Bean, 就是在类上加上@primary
 *         也可以继续使用 @Qualifier指定需要装配的Bean的名字
 *       【注意】
 *           Autowared(required=false) 指定为false 就不必须了会默认赋值为null
 */
@Configuration
@ComponentScan("com.def")
public class MainConfigAutoware {

    @Bean("persondao2")
    public PersonDao personDao(){
        return new PersonDao();
    }
}


@Controller
public class PersonCtroller {
    @Autowired
    private PersonService personService;

}

import org.springframework.stereotype.Repository;

@Repository
public class PersonDao {
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PersonService {
    @Autowired
    private PersonDao personDao;
    public void print(){
        System.out.println(personDao);
    }

    @Override
    public String toString() {
        return "PersonService{" +
                "personDao=" + personDao +
                '}';
    }
}

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    @org.junit.Test
    public void test1(){
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfigAutoware.class);
        PersonService bean = ac.getBean(PersonService.class);
        System.out.println(bean);
        PersonDao bean1 = ac.getBean(PersonDao.class);
        System.out.println(bean1);
    }
}

【特殊  一 】 @Autowared 不仅可以标注 属性位置,还可以构造器、参数、属性、方法

 

@Autowire //标注方法上,Spring容器创建当前对象,就会调用方法,完成赋值

//标注方法上,Spring容器创建当前对象,就会调用方法,完成赋值
//方法使用的参数,自定义类型的值从IOC容器中获取
@Autowired
public void setCar(Car car) {//这个Car就是从容器中获取
this.car = car;
}
 

 

   //放在有参构造器上
@Autowired
public Boos(Car car) { this.car = car; System.out.println("00有参构造器00"); }

 

   //放在参数上
public Boos(@Autowired Car car) { this.car = car; System.out.println("00有参构造器00"); }

 

 //@Bean 标注的方法创建对象的时候,方法参数从容器中获得
    @Bean
    public Person person(Person person){
        return new Person();
    }

 

【特殊 二 】 自定义组件想要使用Spring容器底层的一些组件(ApplicationContext、BeanFactory、等等 ....);

                         只需要自定义实现  xxxxAware  ,在创建对象的时候,会调用接口规定的方法注入相关组件

                     xxxAware,功能使用xxxProcessor,

                                    ApplicationContextAware ==> ApplicationContextAwareProcessor,

第二种 使用@Resource(JSR250) 和 @Inject(JSR330) [java 规范注解]

      @Resource       

                 可以和Autoware 一样,默认按照属性名称装配

                没有能支持@Primary 功能没有,支持@Autoware(reqiured = false)

       

 @Resource(name="bookDao")
  private BookDao bookDao;

 

        @Inject 使用需要导入依赖 

                        <artifactid>javax.inject</artifactid>

  @Inject //和 Autoware 的功能一样,但是不支持required=false这个功能
private BookDao bookDao;

 

AutowiredAnnotationBeanPostProcessor  后置处理器,解析完成自动装配过程

第五部分 : Profile

                 Spring为我们提供了可以根据当前环境,动态激活和切换一系列组件n的功能

开发环境、测试环境、生产环境

数据源(/A)(/B)(/C)



 

posted @ 2019-08-30 13:36  lcj12121  阅读(182)  评论(0编辑  收藏  举报