129.【Spring 注解_IOC】(六)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 129.【Spring 注解_IOC】

4.测试

package com.jsxs.Test;
import com.jsxs.bean.Boss;
import com.jsxs.bean.Car;
import com.jsxs.mapper.BookMapper;
import com.jsxs.config.MainConfigOfAutowried;
import com.jsxs.service.BookService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * @Author Jsxs
 * @Date 2023/8/17 11:23
 * @PackageName:com.jsxs.Test
 * @ClassName: IOCTest_Autowried
 * @Description: TODO
 * @Version 1.0
 */
public class IOCTest_Autowried {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowried.class);
        for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    // 判断是否是是在IOC容器中获取的
        Boss bean = applicationContext.getBean(Boss.class);
        Car bean1 = applicationContext.getBean(Car.class);
        System.out.println(bean);
        System.out.println(bean1);
    }
}

(2).标注在有参构造方法上

创建对象默认是调用无参构造方法的,但是因为我们在有参构造方法上添加了@Autowried,那么我们就会在IOC创建后,创建对象的话就会使用有参构造函数进行创建了。

1.Car.java

package com.jsxs.bean;
import org.springframework.stereotype.Repository;
/**
 * @Author Jsxs
 * @Date 2023/8/14 17:12
 * @PackageName:com.jsxs.bean
 * @ClassName: Car
 * @Description: TODO
 * @Version 1.0
 */
@Repository
public class Car {
    public Car(){
        System.out.println("Car Constructor ....");
    }
    public void init(){
        System.out.println("Car Init...");
    }
    public void destroy(){
        System.out.println("Car Destroy...");
    }
}

2.Boss.java

package com.jsxs.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
/**
 * @Author Jsxs
 * @Date 2023/8/17 17:34
 * @PackageName:com.jsxs.bean
 * @ClassName: Boss
 * @Description: TODO
 * @Version 1.0
 */
@Repository  //⭐扫描后默认加载IOC容器中的组件,容器启动就会(单实列饿汉)调用无参构造器创建对象,再进行初始化赋值等操作。⭐
public class Boss {
    private Car car;
    @Autowired ⭐⭐
    // 标注在方法上,Spring容器创建当前对象,就会调用方法,完成赋值的操作。
    // 方法使用的参数,自定义类型的参数的值是从IOC容器中获取, 比如说 我们启动IOC容器后,就会在IOC容器中找类型未 Car.class 类型的组件
    public Boss(Car car) {
        this.car = car;
    }
    public Boss() {
    }
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    @Override
    public String toString() {
        return "Boss{" +
                "car=" + car +
                '}';
    }
}

3.配置类

package com.jsxs.config;
import com.jsxs.mapper.BookMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
 * @Author Jsxs
 * @Date 2023/8/17 11:14
 * @PackageName:com.jsxs.config
 * @ClassName: MainConfigOfAutowried
 * @Description: TODO
 **/
@Configuration
@ComponentScan(value = "com.jsxs") //⭐⭐扫描
public class MainConfigOfAutowried {
    @Primary
    @Bean("book2")
    public BookMapper bookMapper() {
        BookMapper bookMapper = new BookMapper();
        bookMapper.setLabel("2");
        return bookMapper;
    }
}

4.测试

package com.jsxs.Test;
import com.jsxs.bean.Boss;
import com.jsxs.bean.Car;
import com.jsxs.mapper.BookMapper;
import com.jsxs.config.MainConfigOfAutowried;
import com.jsxs.service.BookService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * @Author Jsxs
 * @Date 2023/8/17 11:23
 * @PackageName:com.jsxs.Test
 * @ClassName: IOCTest_Autowried
 * @Description: TODO
 * @Version 1.0
 */
public class IOCTest_Autowried {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowried.class);
        for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
        Boss bean = applicationContext.getBean(Boss.class);
        Car bean1 = applicationContext.getBean(Car.class);
        System.out.println(bean);
        System.out.println(bean1);
    }
}

(3).@Bean + 方法参数

@Bean+方法参数 ,这里的参数默认是从IOC容器中获取的。默认不写@Autowried 也会自动装配

@Primary
    @Bean("book2")
    public BookMapper bookMapper(Car car) {  //⭐ 这个Car 也是从IOC容器中获取的
        BookMapper bookMapper = new BookMapper();
        bookMapper.setLabel("2");
        return bookMapper;
    }

4.自定义组件使用Spring容器底层的一些组件

(1).xxxAware

自定义组件实现xxxAware: 在创建对象的时候,会调用接口规定的方法注入相关组件。Aware

5.@Profile 切换多个应用场景

(1). 环境搭建

1.依赖

<dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>

2.配置类

package com.jsxs.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.StringValueResolver;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
/**
 * @Author Jsxs
 * @Date 2023/8/17 20:59
 * @PackageName:com.jsxs.config
 * @ClassName: MainConfigOfProfile
 * @Description: TODO   Profile:
 *                          Spring为我们提供的可以根据当前环境,动态的激活和切换一系列bean的功能
 *                          (1).开发环境、测试环境、生产环境
 *
 * @Version 1.0
 */
@PropertySource("classpath:/db.properties")  // 1. 因为要读取外部的文件,所以我们需要指定外部的文件的位置
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware {  // 2.实现EmbeddedValueResolverAware解析器接口,这个接口主要是能够解析 ${} 和 #{}
    @Value("${db.user}")  // 3.  获取外部的文件,并赋值
    private String user;
    @Value("${db.password}")
    private String password;
    @Value("${db.driverClass}")
    private String Driver;
        // 4. 进行依赖注入的操作
    private StringValueResolver stringValueResolver;
    @Bean("DataSourceTest")
    public DataSource dataSourceTest() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/demo1");
        dataSource.setDriverClass(Driver);
        return dataSource;
    }
    @Bean("DataSourceDev")
    public DataSource dataSourceDev() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/library");
        dataSource.setDriverClass(Driver);
        return dataSource;
    }
    @Bean("DataSourceProd")
    public DataSource dataSourceProd() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ckqn");
        // 5. 获取解析到的值
        String value = stringValueResolver.resolveStringValue("${db.driverClass}");
        dataSource.setDriverClass(value);
        return dataSource;
    }
    // 6. 依赖注入
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.stringValueResolver=resolver;
    }
}

3.外部资源文件

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

4.测试

package com.jsxs.Test;
import com.jsxs.config.MainConfigOfProfile;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * @Author Jsxs
 * @Date 2023/8/17 21:31
 * @PackageName:com.jsxs.Test
 * @ClassName: IOCTest_Profile
 * @Description: TODO
 * @Version 1.0
 */
public class IOCTest_Profile {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfProfile.class);
        for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    }
}

(2).根据环境注册bean (环境切换)

如何切换环境呢?

/**
     * 切换环境的方式:
     *  1、使用命令行动态参数:在虚拟机参数位置加载-Dspring.profiles.active=test(test是测试的环境标识)
     *  2、代码的方式激活某种环境
     */
package com.jsxs.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.StringValueResolver;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
/**
 * @Author Jsxs
 * @Date 2023/8/17 20:59
 * @PackageName:com.jsxs.config
 * @ClassName: MainConfigOfProfile
 * @Description: TODO   @Profile:指定组件在哪个环境的情况下才能被注册到容器中。 @Bean: 任何环境下都可以被注册到容器中
 *                      Spring为我们提供的可以根据当前环境,动态的激活和切换一系列bean的功能
 *                      (1).开发环境、测试环境、生产环境
 *                      (2).加了环境标识的bean,只有这个环境被激活的时候才能注册
 * @Version 1.0
 */
@PropertySource("classpath:/db.properties")  // 1. 因为要读取外部的文件,所以我们需要指定外部的文件的位置 ⭐
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware {  // 2.实现EmbeddedValueResolverAware解析器接口,这个接口主要是能够解析 ${} 和 #{}
    @Value("${db.user}")  // 3.  获取外部的文件,并赋值
    private String user;
    @Value("${db.password}")
    private String password;
    @Value("${db.driverClass}")
    private String Driver;
    // 4. 进行依赖注入的操作
    private StringValueResolver stringValueResolver;
//    @Profile("default")  假如我们写的是default,那么就会使用注解下方的数据源
    @Profile("test") ⭐⭐
    @Bean("DataSourceTest")
    public DataSource dataSourceTest() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/demo1");
        dataSource.setDriverClass(Driver);
        return dataSource;
    }
    @Profile("dev")⭐⭐⭐
    @Bean("DataSourceDev")
    public DataSource dataSourceDev() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/library");
        dataSource.setDriverClass(Driver);
        return dataSource;
    }
    @Profile("prod")⭐⭐⭐
    @Bean("DataSourceProd")
    public DataSource dataSourceProd() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ckqn");
        // 5. 获取解析到的值
        String value = stringValueResolver.resolveStringValue("${db.driverClass}");
        dataSource.setDriverClass(value);
        return dataSource;
    }
    // 6. 依赖注入
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.stringValueResolver = resolver;
    }
}
package com.jsxs.Test;
import com.jsxs.config.MainConfigOfProfile;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * @Author Jsxs
 * @Date 2023/8/17 21:31
 * @PackageName:com.jsxs.Test
 * @ClassName: IOCTest_Profile
 * @Description: TODO
 * @Version 1.0
 */
public class IOCTest_Profile {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 1.指定环境 ⭐
        applicationContext.getEnvironment().setActiveProfiles("test");
        // 2.指定配置类 ⭐⭐
        applicationContext.register(MainConfigOfProfile.class);
        // 3.刷新容器  ⭐⭐⭐
        applicationContext.refresh();
        // 4.输出所有的组件
        for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    }
}

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
60 0
|
23天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
165 73
|
20天前
|
XML Java 数据格式
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
106 69
|
18天前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
49 21
|
24天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
23天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
23天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
23天前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
1月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
61 2
|
2月前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
94 4
SpringBoot必须掌握的常用注解!