本文为个人学习笔记:
资料来源:
个人学习尚硅谷 雷丰阳老师的视频 自己总结
学习视频:https://www.bilibili.com/video/BV1gW411W7wy
// 配置类 等于之前的配置文件
@Configuration // 告诉Spring 这是一个配置类
public class MainConfig {
/**
* 功能描述: 配置person
* @Param: []
* @Return: com.jsu.pojo.Person
* @Author: Jsu
*
*
*
*
* 类型为 class="com.jsu.pojo.Person" 返回值类型 Person
* id="person" == person
*/
@Bean // 给容器中主注册一个bean
public Person person(){
return new Person("su",20);// 自己随便定义的person类 只有两个属性
}
}
@Test
public void testMain01() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
String[] names = applicationContext.getBeanDefinitionNames();
for (String name : names) {
System.out.println("bean --- --- " + name);
}
}
@ComponentScan 什么都不填的话 默认是本包
包扫描 只要是标注了@component @controller @service @repository
<context:component-scan base-package="com.jsu"></context:component-scan>
value: 指定要扫描的包
excludeFilters: 扫描的时候按照什么规则排除那些组件
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
includeFilters : 扫描的时候只让那些组件接收扫描
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Repository.class,})
使用includeFilters时候 记得加上 useDefaultFilters = false
@ComponentScans 里面放ComponentScan数组
FilterType.ANNOTATION 按照注解
FilterType.ASSIGNABLE_TYPE 按照给定的类型 type = FilterType.ASSIGNABLE_TYPE,classes = {PersonService.class}
FilterType.ASPECTJ 使用ASPECTJ表达式
FilterType.REGEX 使用正则表达式
FilterType.CUSTOM 自定义过滤规则
// 配置类 等于之前的配置文件
@Configuration // 告诉Spring 这是一个配置类
@ComponentScan(value = "com.jsu",excludeFilters = {
// @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {PersonService.class})
},
includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class}),
// @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Repository.class,})
},useDefaultFilters = false)
public class MainConfig {
@Bean // 给容器中主注册一个bean
public Person person(){
return new Person("su",20);
}
}
// @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class}) 自定义过滤规则
public class MyTypeFilter implements TypeFilter {
/**
* 功能描述:
* metadataReader : 读取到的当前正在扫描的包
* metadataReaderFactory : 可以获取到其他任何类的信息的
* @Param: [metadataReader, metadataReaderFactory]
* @Return: boolean
* @Author: Jsu
*/
@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();
System.out.println("--->" + className);
if (className.contains("er")){
return true; //匹配成功 包含在容器中
}
return false;
}
}
@Conditional({Condition(数组)})
按照一定的条件进行判断,满足条件给容器中注册bean
问题升级:
当系统为windows系统的时候 输出Bill Gates
当系统为linux系统的时候 输出Linux
Conditional 可以放在类上 : 意思是 当不满足条件 就整个配置都不注册组件
@Configuration
public class MainConfig2 {
@Conditional({WindowsConditional.class})
@Bean("bill")
public Person person01(){
return new Person("Bill Gates",62);
}
@Conditional({LinuxConditional.class})
@Bean("linux")
public Person person02(){
return new Person("Linux",48);
}
}
public class LinuxConditional implements Condition {
/**
* 功能描述: 判断是否是Linux 系统
* ConditionContext : 判断条件恩使用的上下文环境
* AnnotatedTypeMetadata: 注释信息
* @Param: [context, metadata]
* @Return: boolean
* @Author: Jsu
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 判断是否是Linux 系统
// 能获取到iod使用的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 获取到类加载器
ClassLoader classLoader = context.getClassLoader();
// 获取当前环境信息
Environment environment = context.getEnvironment();
// 获取到bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();
// 操作系统 使用environment
String property = environment.getProperty("os.name");
if (property.contains("linux")){
return true;
}
return false;
}
}
public class WindowsConditional implements Condition {
/**
* 功能描述: 判断是否是windows 系统
* ConditionContext : 判断条件恩使用的上下文环境
* AnnotatedTypeMetadata: 注释信息
* @Param: [context, metadata]
* @Return: boolean
* @Author: Jsu
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 获取当前环境信息
Environment environment = context.getEnvironment();
// 操作系统 使用environment
String property = environment.getProperty("os.name");
if (property.contains("Windows")){
return true;
}
return false;
}
}
@Test
public void testMain03() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
/**
* 问题升级:
* 当系统为windows系统的时候 输出Bill Gates
* 当系统为linux系统的时候 输出Linux
*/
Environment environment = applicationContext.getEnvironment();
String property = environment.getProperty("os.name"); // 获取当前系统
System.out.println(property); //Windows 10
String[] beanNamesForType = applicationContext.getBeanNamesForType(Person.class);
for (String s : beanNamesForType) {
System.out.println(s);
}
Map<String, Person> beansOfType = applicationContext.getBeansOfType(Person.class);
System.out.println(beansOfType);
}
public class MainConfig2 {
/**
* 默认单实例化 ,对其进行修改
*
* @see @ConfigurableBeanFactory#SCOPE_PROTOTYPE prototype
* @see @ConfigurableBeanFactory#SCOPE_SINGLETON singleton
* @see @org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
* @see @org.springframework.web.context.WebApplicationContext#SCOPE_SESSION
* 常用:
* prototype :多实例
* ioc容器启动并不会去调用方法创建对象放在容器中
* 每次获取的时候才会调用方法创建对象
* singleton :单实例(默认值)
* ioc容器在启动的时候 就会调用方法去创建对象 放到ioc容器中
* 以后每次获取就是直接从容器(map.get)中拿
* 不用:
* request : 同一次请求创建一个实例
* session :同一个session创建一个实例
* 懒加载:
* 单实例bean :默认在容器启动的时候创建对象;
* 懒加载:容器启动不创建对象。第一次使用(获取) Bean创建对象,并初始化;
* @Lazy: 单例模式时候 刚启动的时候从容器中先不获取,当实例化的时候在获取
*/
@Scope("prototype")
@Bean
public Person person() {
return new Person();
}
@Test
public void testMain02() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] names = applicationContext.getBeanDefinitionNames();
for (String name : names) {
System.out.println("bean --- --- " + name);
}
Object bean1 = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean1 == bean2);
}
/**
* 给容器中注册组件
* 1、包扫描+组件标注注解 @Controller @Service @Repository @Component
* 2、@Bean 导入的第三方包里面的组件
* 3、@Import 快速给容器导一个组件
* 1、 @Import() 导入组件 id默认是组件的全类名
* 也可以导入多个
* 2、ImportSelector: 返回需要导入的组件的全类名数组
* 可以将自己写的ImportSelector中返回的数组的内容 注入到容器中
* 3、ImportBeanDefinitionRegistrar : 手动注册bean到容器中
*/
@Import({Color.class,Person.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* 功能描述:
* AnnotationMetadata : 当前类的注解信息
* BeanDefinitionRegistry :BeanDefinition的注册类
* 把所需要添加到容器中的bean,调用
* BeanDefinitionRegistry.registerBeanDefinitions 手工注册进来
* @Param: [importingClassMetadata, registry]
* @Return: void
* @Author: Jsu
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean red = registry.containsBeanDefinition("com.jsu.pojo.Red");
boolean blue = registry.containsBeanDefinition("com.jsu.pojo.Blue");
if (red && blue){ // 判断容器中是否有com.jsu.pojo.Red和com.jsu.pojo.Blue
// 指定bean的定义信息:bean的类型 bean...
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
// 注册一个bean 指定bean名
registry.registerBeanDefinition("rainBow",beanDefinition);
}
}
// 自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {
/**
* 功能描述: 返回值就是导入到容器中的组件全类名
* AnnotationMetadata 当标注Import注解的类的所有注解信息
* @Param: [importingClassMetadata]
* @Return: java.lang.String[]
* @Author: Jsu
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.jsu.pojo.Blue","com.jsu.pojo.Red"};
}
}
// 使用Spring提供的FactoryBean(工厂bean)
// 1、默认获取的是工厂bean调用的getObject创建的对象
// 2、要获取工厂bean本身,我们需要给id前面加上一个 &
// &colorFactoryBean
@Configuration
public class MainConfig2 {
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
}
// 创建一个spring定义的工厂bean
public class ColorFactoryBean implements FactoryBean<Color> {
/**
* 功能描述: 返回一个color对象 返回到容器中
* @Param: []
* @Return: com.jsu.pojo.Color
* @Author: Jsu
*/
@Override
public Color getObject() throws Exception {
System.out.println("ColorFactoryBean getObject...... ");
return new Color();
}
/**
* 功能描述: 返回的类型
* @Param: []
* @Return: java.lang.Class>
* @Author: Jsu
*/
@Override
public Class<?> getObjectType() {
return Color.class;
}
/**
* 功能描述: 是否是单例
* true:单实例 在容器中保存一份
* false:多实例 每次获取都会创建一个新的bean 调用getObject方法
* @Param: []
* @Return: boolean
* @Author: Jsu
*/
@Override
public boolean isSingleton() {
return false;
}
}
@Test
public void testImport(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
// 工厂调用 获取的是调用getObject创建的对象
Object colorFactory = applicationContext.getBean("colorFactoryBean");
Object colorFactory2 = applicationContext.getBean("colorFactoryBean");
System.out.println("bean的类型: "+ colorFactory.getClass());
//bean的类型: class com.jsu.pojo.Color
System.out.println(colorFactory == colorFactory2); // false
// ColorFactoryBean getObject......
// ColorFactoryBean getObject......
// bean的类型: class com.jsu.pojo.Color
// Spring 在FactoryBean中注册 标明当有& 说明是拿工厂bean的本身对象
Object colorFactory3 = applicationContext.getBean("&colorFactoryBean");
System.out.println("bean的类型: "+ colorFactory3.getClass());
}
bean的生命周期:
bean的创建 --- 初始化 --- 销毁的过程
1. Spring对bean进行实例化;
2. Spring将值和bean的引用注入到bean对应的属性中;
3. 加载xxxAware接口
1)、如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法;
2)、如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;
3)、如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationcontext()方法,将bean所在的应用上下文的引用传入进来;
4.如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization()方法;
5.如果bean实现了InitializingBean接口,Spring将调用它们的after-Propertiesset()方法。类似地,如果bean使用init-method声明了初始化方法,该方法也会被调用;
6.如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization()方法;
7.此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
8.如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。
容器管理bean的生命周期
我们可以自定义初始化和销毁的方法;
容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
构造(对象创建)
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
@Configuration
public class MainConfigOfLifeCycle {
// 指定init-method 和 destroy-method 两个方法
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
return new Car();
}
}
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 ...");
}
}
@Test
public void test01( ){
// 创建ioc容器 在创建容器的时候 所有的单实例都会创建完成
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成 .... ");
// car constructor ....
// car init ...
// 容器创建完成 ....
applicationContext.close();
// car destroy ...
}
、
@ComponentScan("com.jsu.pojo")
@Configuration
public class MainConfigOfLifeCycle {
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
return new Car();
}
}
@Component
public class Cat implements InitializingBean , DisposableBean {
public Cat() {
System.out.println(" Cat constructor .... ");
}
/**
* 功能描述: 销毁
*/
@Override
public void destroy() throws Exception {
System.out.println("cat destroy ...");
}
/**
* 功能描述: 初始化
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat init ...");
}
}
@Test
public void test02( ){
// 创建ioc容器 在创建容器的时候 所有的单实例都会创建完成
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成 .... ");
applicationContext.close();
}
@PostConstruct: 在bean创建完成并且属性赋值完成,来执行初始化方法
@PreDestroy: 在bean销毁之前通知我们进行清理工作
@Component
public class Dog {
public Dog() {
System.out.println(" dog constructor ... ");
}
@PostConstruct // 对象创建并赋值之后
public void init(){
System.out.println(" dog PostConstruct ... ");
}
@PreDestroy //在容器移除对象之前
public void destroy( ){
System.out.println(" dog PreDestroy ... ");
}
}
// 测试类还是上面的那个
// BeanPostProcessor[interface]: bean的后置处理器
// 在bean初始化前后进行一些处理工作
// postProcessBeforeInitialization : 初始化之前进行后置处理工作
// postProcessAfterInitialization : 初始化之后进行后置处理工作
@Component // 将后置处理器 加入到容器中
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 功能描述:
* @Param: [o, s]
* Object o: 刚创建的实例
* String s:创建好bean的名字
* @Return: java.lang.Object 可以是the original (传入的 )or a wrapped one(被封装的);
* @Author: Jsu
*/
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessBeforeInitialization before " + s +" " +o);
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessAfterInitialization After " + s +" " +o);
return o;
}
}
//测试类还是上面的
以前导入外部文本文件
<context:property-placeholder location="classpath:person.properties"></context>
现在使用注解版
使用@PropertySource 读取外部配置文件中的k/v 保存到与逆行环境变量中
@PropertySource(value = {"classpath:/person.properties"}) 是个数组 可填多个
@PropertySource(value = {"classpath:/person.properties"}) // 是个数组 可填多个
@Configuration
public class MainConfigOfPropertyValues {
@Bean
public Person person(){
return new Person();
}
}
// 实体类
public class Person {
// 使用@Value赋值;
// 1、基本数值
// 2、可以写SpEL; #{}
// 3、可以写${ };取出配置文件[properties]中的值(在运行环境变量里面的值)`
@Value("张三")
private String name;
@Value("#{20-3}")
private Integer age;
@Value("${person.nickname}")
private String nickename;
}
# 配置文件
person.nickname=xiaosan
// 测试类
public class Main_PropertyValues {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);
public void printBeans(AnnotationConfigApplicationContext applicationContext){
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
@Test
public void test01(){
printBeans(applicationContext);
System.out.println("---------------");
Person person = (Person) applicationContext.getBean("person");
System.out.println(person);
ConfigurableEnvironment environment = applicationContext.getEnvironment();
String property = environment.getProperty("person.nickname");
System.out.println(property);
applicationContext.close();
}
}
自动装配
Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值
1、@Autowired : 自动注入
1)、默认优先按照类型去容器中找对应的组件
applicationContext.getBean(PersonDao.class); (找到就赋值)
2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
3)、@Qualifier( "bookDao" ):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
4)、自动装配默认-定要将属性赋值好,没有就会报错;
可以通过 @Autowired(required=false) 找到就注入 找不到就算了 默认是true 找不到就报错
5)、@Primary 让spring进行自动装配的时候。默认使用首选的bean
当加上@Primary 的时候 @Qualifier就不能添加了
public class PersonService {
@Autowired
PersonDao personDao;
}
2、Spring还支持@Resource(JSR250)和 Inject(JSR330)[java规范的东西]
@Resoure:
可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的
不能和@Qualifier 以及 @Autowired(required=false)一起用
name : 可以指定组件
@Inject
需要导包 javax。inject
和@Autowired功能一样 可以和@Qualifier一起用
没有属性 required=false
// dao层
@Repository
public class PersonDao {
public void print(){
System.out.println("dao ..");
}
}
// service层
@Service
public class PersonService {
@Autowired
PersonDao personDao;
public void print(){
System.out.println(personDao);
}
@Override
public String toString() {
return "PersonService{" +
"personDao=" + personDao +
'}';
}
}
// 配置类
@ComponentScan({"com.jsu.service","com.jsu.dao","com.jsu.controller"})
@Configuration
public class MainConfigOfAutowired {
}
// 测试类
public class Main_Autowired {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
PersonService bean = applicationContext.getBean(PersonService.class);
System.out.println(bean);
PersonDao bean2 = applicationContext.getBean(PersonDao.class);
System.out.println(bean2);
// 两个地址相同 说明是一个PersonDao
applicationContext.close();
}
}
当有两个注入的时候怎么办?
// personDao2
@ComponentScan({"com.jsu.service","com.jsu.dao","com.jsu.controller"})
@Configuration
public class MainConfigOfAutowired {
@Bean("personDao2")
public PersonDao personDao(){
PersonDao personDao = new PersonDao();
personDao.setLabel("2");
return personDao;
}
}
// personDao
@Repository
public class PersonDao {
private String label="1";
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@Override
public String toString() {
return "PersonDao{" +
"label='" + label + '\'' +
'}';
}
}
@Service
public class PersonService {
// @Qualifier("personDao") 加上这个注解后 可指定需要装配的组件的id,而不是使用属性名
@Autowired
PersonDao personDao; // 注入哪个就是哪个
PersonDao personDao2; //
@Override
public String toString() {
return "PersonService{" +
"personDao=" + personDao2 +
'}';
}
}
Spring还支持@Resource(JSR250)和 Inject(JSR330)[java规范的东西]
@Resoure:
可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的
不能和@Qualifier 以及 @Autowired(required=false)一起用
name : 可以指定组件
@Inject
需要导包 javax。inject
和@Autowired功能一样 可以和@Qualifier一起用
没有属性 required=false
3、@Autowired : 构造器,参数,方法,属性
都是从容器中获取参数组件的值
1、 当标注在方法上的时候 【@Bean + 方法参数 参数从容器中获取】
2、 当标注在构造器的时候 【如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动获取】
3、 当标注在参数的时候
/**
* Profile:
* Spring为我们提供的可以根据当前环境,动态激活和切换一系列的组件的功能
* 开发环境 、 测试环境 、 生产环境
* 数据源(/A)(/B)(/C)
* @Profile
* 指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都可以注册这个组件
* 1、 加了环境标识的bean 只有这个环境能被激活 默认是default
* 2、 当写在配置类上的时候 只有是指定的环境的时候,整个配置类里面的所有配置才能生效
*/
@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MainConfigOfProfile {
@Value("${db.user}")
private String user;
@Value("${db.password}")
private String password;
@Value("${db.driverClass}")
private String driverClass;
@Value("${db.jdbcUrl}")
private String jdbcUrl;
@Profile("test")
@Bean("dataSource")
public DataSource dataSource() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("dev")
@Bean("dataSourceDev")
public DataSource dataSourceDev() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("pro")
@Bean("dataSourcePro")
public DataSource dataSourcePro() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setDriverClass(driverClass);
return dataSource;
}
}
# c3p0连接池配置
db.user=root
db.password=000
db.driverClass=com.mysql.jdbc.Driver
db.jdbcUrl=jdbc:mysql://localhost:3306/test
// 测试类
public class Main_Profile {
// 如何改变环境?
// 1、在虚拟机参数位置加载 -Dspring.profiles.active=test
// 2、代码方式
@Test
public void test01() {
/**
* 使用有参构造的时候执行流程
* public AnnotationConfigApplicationContext(Class>... annotatedClasses) {
* this();
* register(annotatedClasses);
* refresh();
* }
* 下面是无参构造 内容自己写
*/
// 2、代码方式
// 无参构造 创建一个applicationContext
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 设置需要激活的环境
applicationContext.getEnvironment().setActiveProfiles("test","dev");
// 配置主配置类
applicationContext.register(MainConfigOfProfile.class);
// 启动构造器
applicationContext.refresh();
String[] beanNamesForType = applicationContext.getBeanNamesForType(DataSource.class);
for (String s : beanNamesForType) {
System.out.println(s);
}
applicationContext.close();
}
}
本文为个人学习笔记:
资料来源:
个人学习尚硅谷 雷丰阳老师的视频 自己总结
学习视频:https://www.bilibili.com/video/BV1gW411W7wy