pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>comgroupId>
<artifactId>spring-bean-factoryartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.1.RELEASEversion>
dependency>
dependencies>
project>
AutowireBean.java
package com.spring.bean;
/**
* @author honey
* @date 2023-08-10 14:51:07
*/
public class AutowireBean {
public void autowire(){
System.out.println("AutowireBean==autowire()");
}
}
UserBean.java
package com.spring.bean;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author honey
* @date 2023-08-10 14:08:14
*/
public class UserBean {
@Autowired
private AutowireBean autowireBean;
public void to() {
System.out.println("UserBean==to()");
autowireBean.autowire();
}
}
SpringConfig.java
package com.spring.config;
import com.spring.bean.AutowireBean;
import com.spring.bean.UserBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author honey
* @date 2023-08-10 14:08:44
*/
@Configuration
public class SpringConfig {
@Bean
public UserBean userBean(){
return new UserBean();
}
@Bean
public AutowireBean autowireBean(){
return new AutowireBean();
}
}
SpringTest01.java
package com.spring.test;
import com.spring.bean.UserBean;
import com.spring.config.SpringConfig;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import java.util.Arrays;
import java.util.Collection;
/**
* @author honey
* @date 2023-08-10 14:09:39
*/
public class SpringTest01 {
public static void main(String[] args) {
// 初始化BeanFactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 获取SpringConfig对应的BeanDefinition
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SpringConfig.class).getBeanDefinition();
// 将BeanDefinition注册到BeanFactory中
beanFactory.registerBeanDefinition("springConfig", beanDefinition);
// 注册注解相关配置的处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
// 通过BeanFactory后置处理器处理SpringConfig中配置的bean(ConfigurationClassPostProcessor)
Collection<BeanFactoryPostProcessor> beanFactoryPostProcessors = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values();
beanFactoryPostProcessors.forEach(
(beanFactoryPostProcessor) -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory)
);
// 通过Bean对象后置处理器处理依赖注入@Autowired(AutowiredAnnotationBeanPostProcessor)和@Resource(CommonAnnotationBeanPostProcessor)
Collection<BeanPostProcessor> beanPostProcessors = beanFactory.getBeansOfType(BeanPostProcessor.class).values();
beanPostProcessors.forEach(
beanFactory::addBeanPostProcessor
);
// 提前初始化单例对象(饿汉式)
beanFactory.preInstantiateSingletons();
// 默认情况下延迟加载(懒汉式)
UserBean userBean = beanFactory.getBean("userBean", UserBean.class);
userBean.to();
System.out.println(userBean);
System.out.println("-------------");
// 输出所有注册到BeanFactory中的beanName
Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach((beanName) -> System.out.println("beanName:" + beanName));
}
}
DefaultListableBeanFactory作为BeanFactory的默认实现类,该类中维护了存储Bean对象的map集合,BeanFactory主要负责生产和管理Bean对象。
// 注册注解相关配置的处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
AnnotationConfigUtils.java
// 通过BeanFactory后置处理器处理SpringConfig中配置的bean(ConfigurationClassPostProcessor)
Collection<BeanFactoryPostProcessor> beanFactoryPostProcessors = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values();
beanFactoryPostProcessors.forEach(
(beanFactoryPostProcessor) -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory)
);
ConfigurationClassPostProcessor:用于从BeanFactory中检测使用了@Configuration注解的类,并将这些类中使用了@Bean注解的方法生成BeanDefinition,注册到BeanFactory中。
ConfigurationClassPostProcessor.java
EventListenerMethodProcessor:主要用于处理@EventListener注解。
// 通过Bean对象后置处理器处理依赖注入@Autowired(AutowiredAnnotationBeanPostProcessor)和@Resource(CommonAnnotationBeanPostProcessor)
Collection<BeanPostProcessor> beanPostProcessors = beanFactory.getBeansOfType(BeanPostProcessor.class).values();
beanPostProcessors.forEach(
beanFactory::addBeanPostProcessor
);
AutowiredAnnotationBeanPostProcessor: 主要用于处理@Autowired注解。
AutowiredAnnotationBeanPostProcessor.java
CommonAnnotationBeanPostProcessor:主要用于处理@Resource注解。
CommonAnnotationBeanPostProcessor.java
// 提前初始化单例对象(饿汉式)
beanFactory.preInstantiateSingletons();
BeanFactory默认采用延迟加载的形式来注入Bean。
BeanFactoryPostProcessor:BeanFactory的后置处理器,是实现spring容器功能扩展的重要接口;
BeanPostProcessor:Bean对象的后置处理器,负责对已创建好的bean对象进行加工处理;
BeanPostProcessor中的两个核心方法:
postProcessBeforeInitialization:在任何初始化方法执行之前执行该方法,如InitializingBean的afterPropertiesSet方法;
postProcessAfterInitialization:在任何初始化方法执行之后执行该方法,如InitializingBean的afterPropertiesSet方法;
ApplicationContext的中文意思是“应用程序上下文”,它继承自BeanFactory接口,除了包含BeanFactory的所有功能之外,在国际化支持、资源访问(如URL和文件)、事件传播等方面进行了良好的支持,被推荐为Java EE应用之首选,可应用在Java APP与Java Web中。
MessageSource是Spring中的转换消息接口,提供了国际化信息的能力。MessageSource用于解析消息,并支持消息的参数化和国际化。Spring包含两个内置的MessageSource实现:ResourceBundleMessageSource和ReloadableResourceBundleMessageSource。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>comgroupId>
<artifactId>spring-application-contextartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.1.RELEASEversion>
dependency>
dependencies>
project>
SpringConfig.java
package com.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
/**
* @author honey
* @date 2023-08-11 01:30:48
*/
@Configuration
public class SpringConfig {
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
// 设置基础名
source.setBasenames("messages/message");
// 设置编码
source.setDefaultEncoding("UTF-8");
return source;
}
}
在resources目录下创建文件夹messages,并在messages文件夹下新增两个配置文件,分别是message_en.properties和message_zh.properties。
message_en.properties
test=test
message_zh.properties
test=测试
SpringTest01.java
package com.spring.test;
import com.spring.config.SpringConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ResourceBundleMessageSource;
import java.util.Locale;
/**
* @author honey
* @date 2023-08-11 01:33:10
*/
public class SpringTest01 {
public static void main(String[] args) {
// MessageSource(国际化的支持)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
ResourceBundleMessageSource messageSource = applicationContext.getBean("messageSource", ResourceBundleMessageSource.class);
System.out.println("中文:" + messageSource.getMessage("test", null, Locale.CHINESE));
System.out.println("英文:" + messageSource.getMessage("test", null, Locale.ENGLISH));
}
}
ResourcePatternResolver用于解析带有*等通配符路径的资源文件,是ResourceLoader接口的拓展接口。
classpath: 只会从target/classes目录下查找文件;
classpath*: 不仅会从target/classes目录下查找文件,还会从所依赖的Jar包中查找文件;
application.properties
name=honey
SpringTest02.java
package com.spring.test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.util.Arrays;
/**
* @author honey
* @date 2023-08-11 02:09:51
*/
public class SpringTest02 {
public static void main(String[] args) throws IOException {
// ResourcePatternResolver(匹配资源路径)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
System.out.println("-------------------------------------------------------------");
System.out.println("读取resources目录下的application.properties");
Resource[] resources1 = applicationContext.getResources("classpath:application.properties");
Arrays.stream(resources1).forEach(System.out::println);
System.out.println("-------------------------------------------------------------");
System.out.println("读取spring-beans-5.2.1.RELEASE.jar!/META-INF/spring.factories");
Resource[] resources2 = applicationContext.getResources("classpath*:META-INF/spring.factories");
Arrays.stream(resources2).forEach(System.out::println);
}
}
SpringTest03.java
package com.spring.test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* @author honey
* @date 2023-08-11 02:31:12
*/
public class SpringTest03 {
public static void main(String[] args) {
// EnvironmentCapable(环境变量配置)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
ConfigurableEnvironment environment = applicationContext.getEnvironment();
String javaHome = environment.getProperty("java_home");
String env = environment.getProperty("env");
System.out.println("java_home:" + javaHome);
System.out.println("env:" + env);
}
}
在启动时需要加上环境变量参数
方式一
方式二
UserInfoEvent.java
package com.spring.event;
import org.springframework.context.ApplicationEvent;
/**
* @author honey
* @date 2023-08-11 02:42:37
*/
public class UserInfoEvent extends ApplicationEvent {
/**
* source事件源
*
* @param source source
*/
public UserInfoEvent(Object source) {
super(source);
}
}
EmailListener.java
package com.spring.listener;
import com.spring.event.UserInfoEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
* @author honey
* @date 2023-08-11 02:44:35
*/
@Component
public class EmailListener {
@EventListener
public void emailListener(UserInfoEvent userInfoEvent) {
System.out.println("当前监听器:emailListener,userInfoEvent:" + userInfoEvent);
}
}
PhoneListener.java
package com.spring.listener;
import com.spring.event.UserInfoEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
* @author honey
* @date 2023-08-11 02:46:40
*/
@Component
public class PhoneListener {
@EventListener
public void phoneListener(UserInfoEvent userInfoEvent) {
System.out.println("当前监听器:phoneListener,userInfoEvent:" + userInfoEvent);
}
}
SpringConfig02.java
package com.spring.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @author honey
* @date 2023-08-11 02:48:54
*/
@Configuration
@ComponentScan(value = {"com.spring.listener"})
public class SpringConfig02 {
}
SpringTest04.java
package com.spring.test;
import com.spring.config.SpringConfig02;
import com.spring.event.UserInfoEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author honey
* @date 2023-08-11 02:47:25
*/
public class SpringTest04 {
public static void main(String[] args) {
// ApplicationEventPublisher(事件发布)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig02.class);
applicationContext.publishEvent(new UserInfoEvent(applicationContext));
}
}
UserBean.java
package com.spring.bean;
/**
* @author honey
* @date 2023-08-11 03:11:09
*/
public class UserBean {
}
spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userBean" class="com.spring.bean.UserBean"/>
beans>
SpringTest05.java
package com.spring.test;
import com.spring.bean.UserBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author honey
* @date 2023-08-11 03:11:51
*/
public class SpringTest05 {
public static void main(String[] args) {
// 读取spring.xml
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
// 从IOC容器中读取对象
UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
System.out.println(userBean);
}
}
SpringTest06.java
package com.spring.test;
import com.spring.bean.UserBean;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* @author honey
* @date 2023-08-11 03:17:20
*/
public class SpringTest06 {
public static void main(String[] args) {
// 从磁盘中读取spring.xml
FileSystemXmlApplicationContext applicationContext = new FileSystemXmlApplicationContext("F:\\spring.xml");
// 从IOC容器中读取对象
UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
System.out.println(userBean);
}
}
SpringConfig03.java
package com.spring.config;
import com.spring.bean.UserBean;
import org.springframework.context.annotation.Bean;
/**
* @author honey
* @date 2023-08-11 03:53:02
*/
public class SpringConfig03 {
@Bean
public UserBean userBean03() {
return new UserBean();
}
}
SpringConfig04.java
package com.spring.config;
import com.spring.bean.UserBean;
import org.springframework.context.annotation.Bean;
/**
* @author honey
* @date 2023-08-11 03:54:27
*/
public class SpringConfig04 {
@Bean
public UserBean userBean04() {
return new UserBean();
}
}
MyImportSelector.java
package com.spring.bean;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* @author honey
* @date 2023-08-11 03:55:37
*/
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.spring.config.SpringConfig04"};
}
}
MyImportBeanDefinitionRegistrar.java
package com.spring.bean;
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;
/**
* @author honey
* @date 2023-08-11 03:55:45
*/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(UserBean.class);
registry.registerBeanDefinition("userBean05", rootBeanDefinition);
}
}
SpringConfig05.java
package com.spring.config;
import com.spring.bean.MyImportBeanDefinitionRegistrar;
import com.spring.bean.MyImportSelector;
import org.springframework.context.annotation.Import;
/**
* @author honey
* @date 2023-08-11 04:02:27
*/
@Import({SpringConfig03.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class SpringConfig05 {
}
SpringTest07.java
package com.spring.test;
import com.spring.bean.UserBean;
import com.spring.config.SpringConfig05;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author honey
* @date 2023-08-11 04:06:39
*/
public class SpringTest07 {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig05.class);
UserBean userBean03 = annotationConfigApplicationContext.getBean("userBean03", UserBean.class);
System.out.println(userBean03);
UserBean userBean04 = annotationConfigApplicationContext.getBean("userBean04", UserBean.class);
System.out.println(userBean04);
UserBean userBean05 = annotationConfigApplicationContext.getBean("userBean05", UserBean.class);
System.out.println(userBean05);
}
}
LinuxCondition.java
package com.spring.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* @author honey
* @date 2023-08-11 04:20:37
*/
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return System.getProperty("os.name").toLowerCase().contains("linux");
}
}
WindowsCondition.java
package com.spring.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* @author honey
* @date 2023-08-11 04:22:04
*/
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return System.getProperty("os.name").toLowerCase().contains("windows");
}
}
SystemOperation.java
package com.spring.condition;
/**
* @author honey
* @date 2023-08-11 04:22:49
*/
public class SystemOperation {
private final String name;
public SystemOperation(String name) {
this.name = name;
}
@Override
public String toString() {
return "SystemOperation{" +
"name='" + name + '\'' +
'}';
}
}
SpringConfig06.java
package com.spring.config;
import com.spring.condition.LinuxCondition;
import com.spring.condition.SystemOperation;
import com.spring.condition.WindowsCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
/**
* @author honey
* @date 2023-08-11 04:23:27
*/
public class SpringConfig06 {
@Bean
@Conditional(value = WindowsCondition.class)
public SystemOperation windowsSystemOperation() {
return new SystemOperation("执行windows命令");
}
@Bean
@Conditional(value = LinuxCondition.class)
public SystemOperation linuxSystemOperation() {
return new SystemOperation("执行linux命令");
}
}
SpringTest08.java
package com.spring.test;
import com.spring.condition.SystemOperation;
import com.spring.config.SpringConfig06;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.Map;
/**
* @author honey
* @date 2023-08-11 04:24:39
*/
public class SpringTest08 {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig06.class);
Map<String, SystemOperation> beansOfType = annotationConfigApplicationContext.getBeansOfType(SystemOperation.class);
System.out.println(beansOfType);
}
}