四、自动装配

一、@Autowired 自动注入

  • 默认优先按照类型在容器中获取组件,:applicationContext.getBean(BookDao.class);

  • 如果该类型有多个实例,再将属性名称作为组件id(本例中的ms)在容器中找,applicationContext.getBean(bookDao)

  • 使用@Qualifier指定要装配的组件的Id,而不是使用属性名称。

  • 使用自动装配,默认情况下,容器中一定要有被装配的组件,若果没有报错,可以使用@Autowired(required = false) 关闭没有组件时装配报错(只能解决容器启动时的报错,业务调用组件没有时还是报错。)

  • @Primary:让Spring在进行自动装配的的时候,默认使用首选的bean

1.1、Controller

@Controller
public class MyController {

    @Autowired(required = false)
    @Qualifier("my1Service")
    private My1Service ms;

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("MyController{");
        sb.append("ms=").append(ms);
        sb.append('}');
        return sb.toString();
    }
}

1.2、Service

/**
*
*    当My1Service这个组件在容器中有多个id不同的bean时候,id=my1Service首先被使用,前提是没有使用
*   @Qualifier注解指明
*/
@Primary
@Service("my1Service")
public class My1Service {
    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("My1Service{asdas");
        sb.append('}');
        return sb.toString();
    }
}

1.3、主配置类

@Configuration
@ComponentScan(value = {"com.jdy.controller","com.jdy.service"})
public class MyConfigOfAutowire {
}

1.4、测试类

 @Test
    public void test12(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfigOfAutowire.class);
        MyController mycontroller = context.getBean(MyController.class);
        System.out.println("bean = " + mycontroller.toString());
    }

二、@Resource和@InJect

  JSR250的@Resource和JSR330的@InJect都属于java规范注解

    • @Resource:可以和Autowired一样实现自动装配,默认是按照组件名称进行装配,

  不支持@Primary功能,没有@Autowired(required = false)

    • @InJect:和Autowired一样,没有@Autowired(required = false)的功能

    • Autowired是spring定义的,@Resource和@InJect是Java提供的

  使用@InJect需要先导入依赖

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

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

  @Autowired的标准位置可以是:构造器、方法、属性

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

  方法使用的参数,自定义类型的值从ioc容器中获取

/**
 * @author Mr.jdy
 * @create 2020-04-21 21:43
 */
@Controller
public class MyController {
    private My1Service ms;

     
    @Autowired(required = false)
    public void setMs(My1Service ms) {
        this.ms = ms;
    }
}
  • 构造器
@Controller
public class MyController {
    private My1Service ms;
    
    @Autowired(required = false)
    public MyController(My1Service ms) {
        this.ms = ms;
    }
}

四、使用Spring底层的组件

  自定义组件:实现XXXAware接口,在创建对象的时候,会调用接口规定的方法,接口返回回调

  每一个Aware都有对应的后置处理器process

  ‘自定义组件想要使用Spring容易顶层的一些组件,(ApplicationContext,BeanFacctory,xxx):自定义组件实现xxxAware;创建对象的时候,会调用接口规定的方法注入相关组件:Aware把Spring底层一些组件注入到自定Bean中。

  xxxAware的功能,使用是xxxProcess来实现的

  Aware的实现(ctrl+h)

@Component
public class MyAware implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("传入的IOC:"+applicationContext);
        this.applicationContext=applicationContext;
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("当前bean的名字"+name);
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        String s = resolver.resolveStringValue("你好${os.name} 我是#{}");
        System.out.println(s);
    }
}

五、@Profile

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

比如有开发环境、测试环境、生产环境连接不同的数据源

引入数据库jar包、

<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>

5.1、主配置文件

/**
 * Profile:
 *         Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
 * 
 * 开发环境、测试环境、生产环境;
 * 数据源:(/A)(/B)(/C);
 * 
 * 
 * @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
 * 
 * 1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
 * 2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
 * 3)、没有标注环境标识的bean在,任何环境下都是加载的;
 */

@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware{
    
    @Value("${db.user}")
    private String user;
    
    private StringValueResolver valueResolver;
    
    private String  driverClass;
    
    
    @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) {
        // TODO Auto-generated method stub
        this.valueResolver = resolver;
        driverClass = valueResolver.resolveStringValue("${db.driverClass}");
    }

}

5.2、dbconfig.properties文件

db.user=root
db.password=root
db.driverClass=com.mysql.jdbc.Driver

5.3、测试

public class IOCTest_Profile {
    
    //1、使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=test
    //2、代码的方式激活某种环境;
    @Test
    public void test01(){
        AnnotationConfigApplicationContext applicationContext = 
                new AnnotationConfigApplicationContext();
        //1、创建一个applicationContext
        //2、设置需要激活的环境
        applicationContext.getEnvironment().setActiveProfiles("dev");
        //3、注册主配置类
        applicationContext.(MainConfigOfProfile.class);
        //4、启动刷新容器
        applicationContext.refresh();
        
        
        String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class);
        for (String string : namesForType) {
            System.out.println(string);
        }
        
        Yellow bean = applicationContext.getBean(Yellow.class);
        System.out.println(bean);
        applicationContext.close();
    }
}

原文地址:https://www.cnblogs.com/jdy1022/p/14006062.html