import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.mvc.Controller;
/
* 测试Spring中的ApplicationContext
*
* @author lzlg
* 2023/3/8 17:56
*/
public class TestSpringApplicationContext {
public static void main(String[] args) {
// testClassPathXmlApplicationContext();
// testFileSystemXmlApplicationContext();
// testAnnotationConfigApplicationContext();
testAnnotationConfigServletWebServerApplicationContext();
}
/
* 文件系统路径下查找Bean的定义xml文件
*/
private static void testFileSystemXmlApplicationContext() {
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("bean01.xml");
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
Bean2 bean2 = context.getBean(Bean2.class);
System.out.println(bean2.getBean1());
}
/
* 类路径下查找Bean的定义xml文件
*/
private static void testClassPathXmlApplicationContext() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
Bean2 bean2 = context.getBean(Bean2.class);
System.out.println(bean2.getBean1());
}
/
* 基于注解的ApplicationContext
*/
private static void testAnnotationConfigApplicationContext() {
// 需指定配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
Bean2 bean2 = context.getBean(Bean2.class);
System.out.println(bean2.getBean1());
}
/
* 基于注解的在web环境使用的ApplicationContext
*/
private static void testAnnotationConfigServletWebServerApplicationContext() {
// 注意不是 AnnotationConfigServletWebApplicationContext
// 必须是 AnnotationConfigServletWebServerApplicationContext
AnnotationConfigServletWebServerApplicationContext context =
new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
@Configuration
static class WebConfig {
// 注入内嵌的Tomcat Servlet容器
@Bean
public ServletWebServerFactory servletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
// Spring处理web请求的入口Servlet
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
// 将内嵌的Tomcat Servlet容器和DispatcherServlet进行关联
@Bean
public DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet) {
return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
}
// 向容器中注入controller处理/hello请求
@Bean("/hello")
public Controller helloController() {
return (request, response) -> {
response.getWriter().println("hello,world.");
return null;
};
}
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public Bean2 bean2(Bean1 bean1) {
Bean2 bean2 = new Bean2();
bean2.setBean1(bean1);
return bean2;
}
}
static class Bean1 {
}
static class Bean2 {
private Bean1 bean1;
public void setBean1(Bean1 bean1) {
this.bean1 = bean1;
}
public Bean1 getBean1() {
return bean1;
}
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.util.Map;
/
* 测试Spring中的BeanFactory
*
* @author lzlg
* 2023/3/5 19:33
*/
public class TestSpringBeanFactory {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 注入bean的定义信息(类是什么,scope范围是什么,初始化方法,销毁方法等)
AbstractBeanDefinition configBeanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(Config.class)
.setScope(ConfigurableBeanFactory.SCOPE_SINGLETON)
.getBeanDefinition();
beanFactory.registerBeanDefinition("config", configBeanDefinition);
// 注入常见的后置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
// 注入后置处理器不会生效,需调用设置方法才能让后置处理器生效
// 获取Bean工厂的后置处理器,可解析@Configuration注解和@Bean注解
Map<String, BeanFactoryPostProcessor> factoryPostProcessorMap = beanFactory.getBeansOfType(
BeanFactoryPostProcessor.class);
// 使Bean工厂后置处理器在Bean工厂中生效
factoryPostProcessorMap.values().forEach(beanFactoryPostProcessor ->
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
// 获取Bean的后置处理器,可解析@Autowired @Resource注解
Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
// 将Bean的后置处理器放置在Bean工厂中生效
beanPostProcessorMap.values().stream()
// 可通过beanFactory.getDependencyComparator()来指定顺序
// 处理@Autowired注解的处理器AutowiredAnnotationBeanPostProcessor默认比
// 处理@Resource注解的处理器CommonAnnotationBeanPostProcessor在前面
// .sorted(beanFactory.getDependencyComparator())
.forEach(beanPostProcessor -> {
System.out.println("==========>>>>>>>" + beanPostProcessor);
beanFactory.addBeanPostProcessor(beanPostProcessor);
});
// Bean1 bean1 = beanFactory.getBean(Bean1.class);
// System.out.println(bean1.getBean2());
// BeanFactory的getBean方法是懒加载,当真正需要Bean时才进行创建,可通过下面方法提前实例化
beanFactory.preInstantiateSingletons();
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// @Autowired注解如果遇到两个实现接口的实例,如果字段名称匹配,则使用字段名称匹配的
// @Resource注解通过指定bean名称进行匹配
System.out.println(beanFactory.getBean(Bean1.class).getInter());
// 当@Autowired和@Resource同时存在时,则看哪个bean的后置处理器在前面,以在前面的为准
// 默认是@Autowired在前,因为其order为Ordered.LOWEST_PRECEDENCE - 2
// 而@Resource注解的order为Ordered.LOWEST_PRECEDENCE - 3
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 获取BeanFactory中定义的bean名称数组
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanDefinitionNames) {
System.out.println(beanName);
}
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public Bean2 bean2() {
return new Bean2();
}
@Bean
public Bean3 bean3() {
return new Bean3();
}
@Bean
public Bean4 bean4() {
return new Bean4();
}
}
interface Inter {
}
static class Bean3 implements Inter {
}
static class Bean4 implements Inter {
}
static class Bean1 {
public Bean1() {
System.out.println("Bean1() 构造...");
}
@Autowired
public Bean2 bean2;
public Bean2 getBean2() {
return bean2;
}
// 当@Autowired和@Resource同时存在时
@Autowired
@Resource(name = "bean4")
public Inter bean3;
// 通过指定名称解决冲突
// @Resource(name = "bean4")
// public Inter bean3;
// 通过指定字段名称解决冲突
// @Autowired
// public Inter bean3;
public Inter getInter() {
return bean3;
}
}
static class Bean2 {
public Bean2() {
System.out.println("Bean2() 构造...");
}
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/
* Spring中Bean的生命周期: 创建(构造), 依赖注入, 初始化, 销毁
*
* @author lzlg
* 2023/3/8 19:19
*/
@Component("springBeanLifeCycle")
public class SpringBeanLifeCycle {
public SpringBeanLifeCycle() {
System.out.println("构造 SpringBeanLifeCycle");
}
@Autowired
public void autowire(@Value("${JAVA_HOME}") String javaHome) {
System.out.println("依赖注入: " + javaHome);
}
@PostConstruct
public void init() {
System.out.println("初始化...");
}
@PreDestroy
public void destroy() {
System.out.println("销毁...");
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
/
* Spring中生命周期中的Bean后置处理器
*
* @author lzlg
* 2023/3/8 19:26
*/
@Component
public class MyLifeCycleBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("springBeanLifeCycle")) {
System.out.println(">>>>>> postProcessBeforeDestruction在Bean销毁之前调用,如@PreDestroy");
}
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("springBeanLifeCycle")) {
System.out.println(">>>>>> postProcessBeforeInstantiation在Bean实例化(构造)之前调用,此方法返回的Bean会替换原来的");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("springBeanLifeCycle")) {
System.out.println(">>>>>> postProcessAfterInstantiation在Bean实例化(构造)之后调用,返回false则跳过依赖注入");
return true;
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("springBeanLifeCycle")) {
System.out.println(">>>>>> postProcessProperties在Bean依赖注入阶段执行,如@Autowired,@Value,@Resource");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("springBeanLifeCycle")) {
System.out.println(">>>>>> postProcessBeforeInitialization在Bean初始化之前调用,此方法返回的Bean会替换原来的," +
"如@PostConstruct,@ConfigurationProperties");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("springBeanLifeCycle")) {
System.out.println(">>>>>> postProcessAfterInitialization在Bean初始化之后调用,此方法返回的Bean会替换原来的," +
"如代理增强");
}
return bean;
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/
* 启动类
*
* @author lzlg
* 2023/3/8 19:19
*/
@SpringBootApplication
public class SecondApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SecondApplication.class, args);
context.close();
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
/
* 测试Spring中常见的Bean后置处理器
*
* @author lzlg
* 2023/3/8 19:56
*/
public class TestSpringBeanPostProcessor {
public static void main(String[] args) {
// GenericApplicationContext容器比较干净
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("bean1", Bean1.class);
context.registerBean("bean2", Bean2.class);
context.registerBean("bean3", Bean3.class);
context.registerBean("bean4", Bean4.class);
// 解析@Autowired和@Value注解的后置处理器
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
// 要解析@Value中的${}信息,还需向context中的beanFactory添加解析器
context.getDefaultListableBeanFactory().setAutowireCandidateResolver(
new ContextAnnotationAutowireCandidateResolver());
// 解析@Resource,@PostConstruct,@PreDestroy注解的后置处理器
context.registerBean(CommonAnnotationBeanPostProcessor.class);
// 可以看到@Resource注解先于@Autowired进行解析,因为处理器的排序造成的
// CommonAnnotationBeanPostProcessor的优先级是Ordered.LOWEST_PRECEDENCE - 3
// AutowiredAnnotationBeanPostProcessor的优先级是Ordered.LOWEST_PRECEDENCE - 2
// 数值越小的优先级越高
// 解析Spring Boot中的注解@ConfigurationProperties
ConfigurationPropertiesBindingPostProcessor.register(context);
context.refresh();
// 查看Bean4中绑定的属性解析了没有
System.out.println(context.getBean(Bean4.class));
context.close();
}
static class Bean1 {
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2) {
System.out.println("@Autowired 依赖注入... bean2");
this.bean2 = bean2;
}
private String javaHome;
@Autowired
public void setJavaHome(@Value("${JAVA_HOME}") String javaHome) {
System.out.println("@Value 依赖注入... " + javaHome);
this.javaHome = javaHome;
}
private Bean3 bean3;
@Resource
public void setBean3(Bean3 bean3) {
System.out.println("@Resource 依赖注入... bean3");
this.bean3 = bean3;
}
@PostConstruct
public void init() {
System.out.println("@PostConstruct Bean1 初始化...");
}
@PreDestroy
public void destroy() {
System.out.println("@PreDestroy Bean1 销毁...");
}
}
static class Bean2 {
}
static class Bean3 {
}
@ConfigurationProperties(prefix = "java")
static class Bean4 {
private String home;
private String version;
public String getHome() {
return home;
}
public String getVersion() {
return version;
}
public void setHome(String home) {
this.home = home;
}
public void setVersion(String version) {
this.version = version;
}
@Override
public String toString() {
return "Bean4{" +
"home='" + home + '\'' +
", version='" + version + '\'' +
'}';
}
}
}
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.env.StandardEnvironment;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/
* 测试Spring中解析@Autowired注解的Bean后置处理器
*
* @author lzlg
* 2023/3/8 19:56
*/
public class TestAutowiredBeanPostProcessor {
public static void main(String[] args) throws Throwable {
// 使用BeanFactory进行测试
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 使用registerSingleton注入单例bean,new出的bean则是成品Bean,不会触发创建过程,依赖注入,初始化
beanFactory.registerSingleton("bean2", new Bean2());
beanFactory.registerSingleton("bean3", new Bean3());
// 解析@Value注解的解析器
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
// 解析@Value中的${}表达式
beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);
// 添加@Autowired注解处理器
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);
// 1.AutowiredAnnotationBeanPostProcessor中进行注入处理的方法是postProcessProperties
Bean1 bean1 = new Bean1();
processor.postProcessProperties(null, bean1, "bean1");
System.out.println(bean1);
// 2.postProcessProperties中进行依赖注入的有两个步骤
// 第一个是private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz,
// @Nullable PropertyValues pvs) 方法
// 第二个是InjectionMetadata对象的public void inject(Object target, @Nullable String beanName,
// @Nullable PropertyValues pvs) throws Throwable方法
Method findAutowiringMetadataMethod = AutowiredAnnotationBeanPostProcessor.class
.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadataMethod.setAccessible(true);
// 反射调用findAutowiringMetadata方法
InjectionMetadata injectionMetadata = (InjectionMetadata) findAutowiringMetadataMethod
.invoke(processor, "bean1", Bean1.class, null);
// 进行依赖注入,注入时按照类型进行查找
injectionMetadata.inject(bean1, "bean1", null);
System.out.println(bean1);
// 3.InjectionMetadata的依赖注入流程
// 如果是字段上有@Autowired注解
Field bean3Field = Bean1.class.getDeclaredField("bean3");
DependencyDescriptor bean3DependencyDescriptor = new DependencyDescriptor(bean3Field, false);
Object bean3 = beanFactory.doResolveDependency(bean3DependencyDescriptor, null, null, null);
System.out.println(bean3);
// 如果是方法上有@Autowired注解
Method bean2Method = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
DependencyDescriptor bean2DependencyDescriptor = new DependencyDescriptor(
new MethodParameter(bean2Method, 0), true);
Object bean2 = beanFactory.doResolveDependency(bean2DependencyDescriptor, null, null, null);
System.out.println(bean2);
// 如果方法上是@Value注入
Method javaHomeMethod = Bean1.class.getDeclaredMethod("setJavaHome", String.class);
DependencyDescriptor javaHomeDependencyDescriptor = new DependencyDescriptor(
new MethodParameter(javaHomeMethod, 0), true);
Object javaHome = beanFactory.doResolveDependency(javaHomeDependencyDescriptor, null, null, null);
System.out.println(javaHome);
}
static class Bean1 {
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2) {
System.out.println("@Autowired 依赖注入... bean2");
this.bean2 = bean2;
}
private String javaHome;
@Autowired
public void setJavaHome(@Value("${JAVA_HOME}") String javaHome) {
System.out.println("@Value 依赖注入... " + javaHome);
this.javaHome = javaHome;
}
@Autowired
private Bean3 bean3;
@Resource
public void setBean3(Bean3 bean3) {
System.out.println("@Resource 依赖注入... bean3");
this.bean3 = bean3;
}
@PostConstruct
public void init() {
System.out.println("@PostConstruct Bean1 初始化...");
}
@PreDestroy
public void destroy() {
System.out.println("@PreDestroy Bean1 销毁...");
}
@Override
public String toString() {
return "Bean1{" +
"bean2=" + bean2 +
", javaHome='" + javaHome + '\'' +
", bean3=" + bean3 +
'}';
}
}
static class Bean2 {
}
static class Bean3 {
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.util.Map;
/
* 测试Spring中的BeanFactory
*
* @author lzlg
* 2023/3/5 19:33
*/
public class TestSpringBeanFactory {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 注入bean的定义信息(类是什么,scope范围是什么,初始化方法,销毁方法等)
AbstractBeanDefinition configBeanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(Config.class)
.setScope(ConfigurableBeanFactory.SCOPE_SINGLETON)
.getBeanDefinition();
beanFactory.registerBeanDefinition("config", configBeanDefinition);
// 注入常见的后置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
// 注入后置处理器不会生效,需调用设置方法才能让后置处理器生效
// 获取Bean工厂的后置处理器,可解析@Configuration注解和@Bean注解
Map<String, BeanFactoryPostProcessor> factoryPostProcessorMap = beanFactory.getBeansOfType(
BeanFactoryPostProcessor.class);
// 使Bean工厂后置处理器在Bean工厂中生效
factoryPostProcessorMap.values().forEach(beanFactoryPostProcessor ->
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
// 获取Bean的后置处理器,可解析@Autowired @Resource注解
Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
// 将Bean的后置处理器放置在Bean工厂中生效
beanPostProcessorMap.values().stream()
// 可通过beanFactory.getDependencyComparator()来指定顺序
// 处理@Autowired注解的处理器AutowiredAnnotationBeanPostProcessor默认比
// 处理@Resource注解的处理器CommonAnnotationBeanPostProcessor在前面
// .sorted(beanFactory.getDependencyComparator())
.forEach(beanPostProcessor -> {
System.out.println("==========>>>>>>>" + beanPostProcessor);
beanFactory.addBeanPostProcessor(beanPostProcessor);
});
// Bean1 bean1 = beanFactory.getBean(Bean1.class);
// System.out.println(bean1.getBean2());
// BeanFactory的getBean方法是懒加载,当真正需要Bean时才进行创建,可通过下面方法提前实例化
beanFactory.preInstantiateSingletons();
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// @Autowired注解如果遇到两个实现接口的实例,如果字段名称匹配,则使用字段名称匹配的
// @Resource注解通过指定bean名称进行匹配
System.out.println(beanFactory.getBean(Bean1.class).getInter());
// 当@Autowired和@Resource同时存在时,则看哪个bean的后置处理器在前面,以在前面的为准
// 默认是@Autowired在前,因为其order为Ordered.LOWEST_PRECEDENCE - 2
// 而@Resource注解的order为Ordered.LOWEST_PRECEDENCE - 3
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 获取BeanFactory中定义的bean名称数组
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanDefinitionNames) {
System.out.println(beanName);
}
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public Bean2 bean2() {
return new Bean2();
}
@Bean
public Bean3 bean3() {
return new Bean3();
}
@Bean
public Bean4 bean4() {
return new Bean4();
}
}
interface Inter {
}
static class Bean3 implements Inter {
}
static class Bean4 implements Inter {
}
static class Bean1 {
public Bean1() {
System.out.println("Bean1() 构造...");
}
@Autowired
public Bean2 bean2;
public Bean2 getBean2() {
return bean2;
}
// 当@Autowired和@Resource同时存在时
@Autowired
@Resource(name = "bean4")
public Inter bean3;
// 通过指定名称解决冲突
// @Resource(name = "bean4")
// public Inter bean3;
// 通过指定字段名称解决冲突
// @Autowired
// public Inter bean3;
public Inter getInter() {
return bean3;
}
}
static class Bean2 {
public Bean2() {
System.out.println("Bean2() 构造...");
}
}
}
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
/
* 测试常见的Bean工厂后置处理器
*
* @author lzlg
* 2023/3/9 18:25
*/
public class TestBeanFactoryPostProcessor {
public static void main(String[] args) throws Exception {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config", Config.class);
// 注入自己编写的bean工厂后置处理器
// context.registerBean(MyComponentScanPostProcessor.class);
// 解析@Bean注解
context.registerBean(MyAtBeanPostProcessor.class);
// 解析Mapper接口
context.registerBean(MyMapperPostProcessor.class);
context.refresh();
System.out.println(">>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<");
// 打印容器中的bean名称
String[] definitionNames = context.getBeanDefinitionNames();
for (String definitionName : definitionNames) {
System.out.println(definitionName);
}
context.close();
}
/
* 测试常见的Bean工厂后置处理器
*/
private static void testBeanFactoryPostProcessor() {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config", Config.class);
// 如需配置类生效,需注入ConfigurationClassPostProcessor这个处理器
// 会解析@ComponentScan @Bean @Import @ImportResource
context.registerBean(ConfigurationClassPostProcessor.class);
// mybatis中使用的扫描包的bean工厂后置处理器MapperScannerConfigurer
// 但需指定扫描的包信息
context.registerBean(MapperScannerConfigurer.class, bd -> {
bd.getPropertyValues().add("basePackage", "com.lzlg.study.spring.third.mapper");
});
context.refresh();
// 打印容器中的bean名称
String[] definitionNames = context.getBeanDefinitionNames();
for (String definitionName : definitionNames) {
System.out.println(definitionName);
}
context.close();
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;
import java.io.IOException;
/
* 自定义实现@ComponentScan注解功能的Bean工厂后置处理器
*
* @author lzlg
* 2023/3/9 19:14
*/
public class MyComponentScanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// >>>>>自己实现Bean工厂后置处理器的逻辑<<<<<
// 查看配置类中是否有ComponentScan注解
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
// 如果有
try {
if (componentScan != null) {
// 获取注解上的包名信息
String[] basePackages = componentScan.basePackages();
for (String basePackage : basePackages) {
// System.out.println(basePackage);
// 将包名转换为类路径下的class文件存放路径
// com.lzlg.study.spring.third.component 变为
// classpath*:com/lzlg/study/spring/third/component//*.class
String classpath = "classpath*:" + basePackage.replace(".", "/") + "//*.class";
// System.out.println(classpath);
// 根据路径使用CachingMetadataReaderFactory进行读取
CachingMetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
// 获取类路径下的资源
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(classpath);
// 通过注解生成Bean名称
AnnotationBeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
// Bean2是加了@Component注解的,Bean3是@Service注解(属于@Component的派生注解)
// Bean4无任何注解
for (Resource resource : resources) {
// System.out.println(resource);
// System.out.println(">>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<");
// 读取类的元信息
MetadataReader metadataReader = readerFactory.getMetadataReader(resource);
// Bean的类名
String beanClassName = metadataReader.getClassMetadata().getClassName();
// 注解元信息
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
// System.out.println("类名是: " + beanClassName);
// System.out.println("是否加了@Component注解: " +
// metadata.hasAnnotation(Component.class.getName()));
// System.out.println("是否加了@Component的派生注解: " +
// metadata.hasMetaAnnotation(Component.class.getName()));
// 如果有@Component注解和其派生注解
if (metadata.hasAnnotation(Component.class.getName())
|| metadata.hasMetaAnnotation(Component.class.getName())) {
// 创建Bean定义信息
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(beanClassName).getBeanDefinition();
// 生成Bean名称
String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry);
// 注册进Bean工厂中
registry.registerBeanDefinition(beanName, beanDefinition);
}
}
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/
* 自定义解析@Bean注解的后置工厂处理器
*
* @author lzlg
* 2023/3/9 19:46
*/
public class MyAtBeanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// >>>>>>>>>>>自己编写解析@Bean注解的Bean工厂后置处理器<<<<<<<<<<<<
// 读取元信息的工厂
CachingMetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
// 读取配置类的元信息
MetadataReader metadataReader;
try {
metadataReader = readerFactory.getMetadataReader(
new ClassPathResource("com/lzlg/study/spring/postprocessor/Config.class"));
} catch (IOException e) {
throw new RuntimeException(e);
}
// 获取被@Bean注解标注的方法,没有@Bean注解的方法则不会解析
Set<MethodMetadata> annotatedMethods = metadataReader.getAnnotationMetadata()
.getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : annotatedMethods) {
// System.out.println(method);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
// 指定工厂方法,且是哪个Bean实例(配置类)的方法
builder.setFactoryMethodOnBean(method.getMethodName(), "config");
// 工厂方法和构造注入都是使用AUTOWIRE_CONSTRUCTOR这种类型的装配模式
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
// 获取方法上@Bean注解指定的初始化方法
Object initMethodObj = Objects.requireNonNull(method.getAnnotationAttributes(Bean.class.getName()))
.get("initMethod");
if (initMethodObj != null) {
String initMethod = String.valueOf(initMethodObj);
// 设置初始化方法
builder.setInitMethodName(initMethod);
}
// 注入bean工厂中,bean名称是方法名称
registry.registerBeanDefinition(method.getMethodName(), builder.getBeanDefinition());
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(Configuration.class);
for (Map.Entry<String, Object> entry : beansWithAnnotation.entrySet()) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(entry.getKey());
}
}
}
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import java.io.IOException;
/
* 自定义Mapper接口Bean工厂后置处理器
*
* @author lzlg
* 2023/3/9 20:16
*/
public class MyMapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
try {
// 获取类路径下的Mapper接口class资源
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources("com/lzlg/study/spring/postprocessor/mapper//*.class");
// 元信息读取工厂
CachingMetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
// 通过注解获取bean名称的生成器
AnnotationBeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
for (Resource resource : resources) {
// 获取元信息读取器
MetadataReader reader = readerFactory.getMetadataReader(resource);
// 有@Mapper注解的才进行处理
if (reader.getAnnotationMetadata().hasAnnotation(Mapper.class.getName())) {
// 获取类的元信息
ClassMetadata classMetadata = reader.getClassMetadata();
// 类必须是接口才进行处理
if (classMetadata.isInterface()) {
// 创建MapperFactoryBean的BeanDefinition信息
AbstractBeanDefinition mapperFactoryBeanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(MapperFactoryBean.class)
// MapperFactoryBean<Mapper1> factoryBean = new MapperFactoryBean<>(Mapper1.class);
// factoryBean.setSqlSessionFactory(sqlSessionFactory);
// return factoryBean;
.addConstructorArgValue(classMetadata.getClassName())
// 通过类查找到sqlSessionFactory
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
.getBeanDefinition();
// bean名称应该是Mapper接口实例bean的名称,而不是mapperFactoryBeanDefinition的名称
// 再次定义一个Mapper接口实例的Bean定义信息,专门用来生成Bean名称
AbstractBeanDefinition mapperBeanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
// 生成Bean名称
String beanName = beanNameGenerator.generateBeanName(mapperBeanDefinition, registry);
// 注意要用mapperFactoryBeanDefinition,也就是工厂bean定义信息
registry.registerBeanDefinition(beanName, mapperFactoryBeanDefinition);
}
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
import com.alibaba.druid.pool.DruidDataSource;
import com.lzlg.study.spring.postprocessor.component.Bean4;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
/
* 配置类
*
* @author lzlg
* 2023/3/9 18:26
*/
@ComponentScan("com.lzlg.study.spring.postprocessor.component")
@Configuration
public class Config {
public Bean4 bean4() {
return new Bean4();
}
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean(initMethod = "init")
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("lzlg520!QAZ@WSX");
return dataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
/
* Spring中是通过注入MapperFactoryBean<T>实现创建Mapper接口的Bean实例
*/
// @Bean
// public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory) {
// MapperFactoryBean<Mapper1> factoryBean = new MapperFactoryBean<>(Mapper1.class);
// factoryBean.setSqlSessionFactory(sqlSessionFactory);
// return factoryBean;
// }
//
// @Bean
// public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory) {
// MapperFactoryBean<Mapper2> factoryBean = new MapperFactoryBean<>(Mapper2.class);
// factoryBean.setSqlSessionFactory(sqlSessionFactory);
// return factoryBean;
// }
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
/
* 测试Spring内置功能接口
*
* @author lzlg
* 2023/3/9 21:02
*/
public class MyBean implements BeanNameAware, ApplicationContextAware, InitializingBean {
@Override
public void setBeanName(String name) {
System.out.println("当前bean: " + this + " 名字是: " + name);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("当前bean: " + this + " InitializingBean接口初始化方法afterPropertiesSet()");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("当前bean: " + this + " 容器是: " + applicationContext);
}
@PostConstruct
public void init() {
System.out.println("当前bean: " + this + " @PostConstruct初始化,方法init()");
}
}
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/
* 失效的初始化配置
*
* @author lzlg
* 2023/3/9 21:08
*/
@Configuration
public class MyEffectConfig implements ApplicationContextAware, InitializingBean {
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println(MyEffectConfig.class.getName() + " 注入 ApplicationContext");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(MyNoEffectConfig.class.getName() + " 初始化");
}
@Bean
public BeanFactoryPostProcessor myEffectProcessor() {
return beanFactory -> {
System.out.println("执行 myEffectProcessor");
};
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
/
* 失效的初始化配置
*
* @author lzlg
* 2023/3/9 21:08
*/
@Configuration
public class MyNoEffectConfig {
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println(MyNoEffectConfig.class.getName() + " 注入 ApplicationContext");
}
@PostConstruct
public void init() {
System.out.println(MyNoEffectConfig.class.getName() + " 初始化");
}
@Bean
public BeanFactoryPostProcessor myNoEffectProcessor() {
return beanFactory -> {
System.out.println("执行 myNoEffectProcessor");
};
}
}
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
/
* @author lzlg
* 2023/3/9 21:05
*/
public class TestSpring {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
// context.registerBean("myBean", MyBean.class);
// context.registerBean("myNoEffectConfig", MyNoEffectConfig.class);
// 通过实现Aware和InitializingBean相关接口,配置类中定义的后置处理器不会干扰到配置类的初始化
context.registerBean("myEffectConfig", MyEffectConfig.class);
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
context.registerBean(CommonAnnotationBeanPostProcessor.class);
context.registerBean(ConfigurationClassPostProcessor.class);
context.refresh();
context.close();
}
}
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/
* 测试Spring使用FactoryBean
*
* @author lzlg
* 2023/4/8 21:33
*/
public class TestSpringFactoryBean {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyBeanConfig.class);
Object bean1 = context.getBean("bean");
System.out.println(bean1);
Object bean2 = context.getBean("bean");
System.out.println(bean2);
Object bean3 = context.getBean("bean");
System.out.println(bean3);
System.out.println(">>>>>>>>>>>>>>>>>>>>获取FactoryBean的方式: ");
System.out.println(context.getBean(MyBeanFactory.class));
System.out.println(context.getBean("&bean"));
// 被FactoryBean创建的产品
// 会认为创建,依赖注入,Aware接口回调,初始化前这些都是FactoryBean的职责,这些流程都不会走
// 唯有后初始化的流程会走,也就是产品可以被代理增强
//
// 单例的产品不会存储于BeanFactory的singletonObjects(单例池)成员中,而是另一个factoryBeanObjectCache成员中
// 按名字去获取时,拿到的是产品对象,名字前面加 & 获取的是工厂对象
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/
* 对于FactoryBean,只在初始化后可进行增强,故可对FactoryBean进行代理增强
*
* @author lzlg
* 2023/4/8 21:38
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
/
* 初始化前
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("bean") && bean instanceof MyBean) {
System.out.println("MyBeanPostProcessor, postProcessBeforeInitialization...");
}
return bean;
}
/
* 初始化后
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("bean") && bean instanceof MyBean) {
System.out.println("MyBeanPostProcessor, postProcessAfterInitialization...");
}
return bean;
}
}
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/
* @author lzlg
* 2023/4/8 21:36
*/
@Component("bean")
public class MyBeanFactory implements FactoryBean<MyBean> {
@Override
public MyBean getObject() throws Exception {
MyBean bean = new MyBean();
System.out.println("factory create bean...");
return bean;
}
/
* 决定了getObject()方法被调用一次还是多次
* 是单例则只调用一次
*/
@Override
public boolean isSingleton() {
return true;
}
/
* 返回Bean的类,这样可通过类型获取Bean
*/
@Override
public Class<?> getObjectType() {
return MyBean.class;
}
}
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/
* @author lzlg
* 2023/4/8 21:34
*/
@Configuration
@ComponentScan
public class MyBeanConfig {
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
/
* @author lzlg
* 2023/4/8 21:34
*/
public class MyBean implements BeanFactoryAware {
private InjectBean bean;
@Autowired
public void setBean(InjectBean bean) {
System.out.println("MyBean @Autowired...");
this.bean = bean;
}
public InjectBean getBean() {
return bean;
}
@PostConstruct
public void init() {
System.out.println("MyBean init()...");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("MyBean SetBeanFactory...");
}
}
import org.springframework.stereotype.Component;
/
* @author lzlg
* 2023/4/8 21:34
*/
@Component
public class InjectBean {
}
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
/
* @author lzlg
* 2023/3/9 21:19
*/
public class MyInitBean implements InitializingBean {
@PostConstruct
public void init() {
System.out.println("@PostConstruct 初始化");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean接口 初始化");
}
public void initMethod() {
System.out.println("调用@Bean中的initMethod方法");
}
}
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
/
* 测试初始化Bean的执行顺序
* 注解@PostConstruct > InitializingBean > @Bean中的initMethod
* ===========================================================
* 测试销毁Bean的执行顺序
* 注解@Bean中的destroyMethod > 注解@PreDestroy > DisposableBean
*
* @author lzlg
* 2023/3/9 21:16
*/
public class TestInitDestroyOrder {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(context);
context.registerBean(MyConfig.class);
context.refresh();
context.close();
}
@Configuration
static class MyConfig {
@Bean(initMethod = "initMethod")
public MyInitBean myInitBean() {
return new MyInitBean();
}
@Bean(initMethod = "destroyMethod")
public MyDestroyBean myDestroyBean() {
return new MyDestroyBean();
}
}
}
import org.springframework.beans.factory.DisposableBean;
import javax.annotation.PreDestroy;
/
* @author lzlg
* 2023/3/9 21:19
*/
public class MyDestroyBean implements DisposableBean {
@PreDestroy
public void beforeDestroy() {
System.out.println("@PreDestroy 销毁");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean 销毁");
}
public void destroyMethod() {
System.out.println("@Bean中定义的destroyMethod方法");
}
}
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/
* application的scope
*
* @author lzlg
* 2023/3/10 18:47
*/
@Scope("application")
@Component
public class BeanForApplication {
@PreDestroy
public void destroy() {
System.out.println("BeanForApplication destroy...");
}
}
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/
* request的scope
*
* @author lzlg
* 2023/3/10 18:47
*/
@Scope("request")
@Component
public class BeanForRequest {
@PreDestroy
public void destroy() {
System.out.println("BeanForRequest destroy...");
}
}
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/
* session的scope
*
* @author lzlg
* 2023/3/10 18:47
*/
@Scope("session")
@Component
public class BeanForSession {
@PreDestroy
public void destroy() {
System.out.println("BeanForSession destroy...");
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/
* @author lzlg
* 2023/3/10 18:49
*/
@RestController
public class MyScopeController {
// 在request,session,application scope的bean在单例Bean中(MyScopeController)
// 进行注入需要使用@Lazy生成代理
@Lazy
@Autowired
private BeanForRequest beanForRequest;
@Lazy
@Autowired
private BeanForSession beanForSession;
@Lazy
@Autowired
private BeanForApplication beanForApplication;
@GetMapping("/test")
public String test(HttpServletRequest request, HttpSession session) {
return "<ol>\n" +
" <li>BeanForRequest: " + beanForRequest + "</li>\n" +
" <li>BeanForSession: " + beanForSession + "</li>\n" +
" <li>BeanForApplication: " + beanForApplication + "</li>\n" +
"</ol>";
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/
* 测试Spring中scope
* 共有5种scope: singleton, prototype, request, session, application
*
* @author lzlg
* 2023/3/10 18:45
*/
@SpringBootApplication
public class SixthApplication {
public static void main(String[] args) {
SpringApplication.run(SixthApplication.class, args);
}
}
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/
* 单例Bean注入prototype的scope的bean失效问题
*
* @author lzlg
* 2023/3/10 19:06
*/
@Component
public class E {
@Lazy
@Autowired
private F1 f1;
public F1 getF1() {
return f1;
}
@Autowired
private F2 f2;
public F2 getF2() {
return f2;
}
@Autowired
private ObjectFactory<F3> f3;
public F3 getF3() {
return f3.getObject();
}
@Autowired
private ApplicationContext context;
public F4 getF4() {
return context.getBean(F4.class);
}
}
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
/
* @author lzlg
* 2023/3/10 19:07
*/
@ComponentScan("com.lzlg.study.spring.scope")
public class TestScopeApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestScopeApp.class);
E e = context.getBean(E.class);
// 单例Bean(这里是E)注入多例Bean(是F1)时
// 单例Bean进行依赖注入时只会进行一次,所以每次get时都返回同一个bean
// 解决方法一: 使用@Lazy注解,会创建注入的Bean的代理对象,延迟了多例Bean的创建
System.out.println(e.getF1().getClass());
System.out.println(e.getF1());
System.out.println(e.getF1());
System.out.println(e.getF1());
System.out.println("===========================================");
// 解决方法二: 在多例bean的@Scope注解的proxyMode属性改为ScopedProxyMode=TARGET_CLASS
System.out.println(e.getF2().getClass());
System.out.println(e.getF2());
System.out.println(e.getF2());
System.out.println(e.getF2());
System.out.println("===========================================");
// 解决方法三: 注入ObjectFactory<T>工厂bean
System.out.println(e.getF3().getClass());
System.out.println(e.getF3());
System.out.println(e.getF3());
System.out.println(e.getF3());
System.out.println("===========================================");
// 解决方法四: 使用ApplicationContext容器获取多例bean
System.out.println(e.getF4().getClass());
System.out.println(e.getF4());
System.out.println(e.getF4());
System.out.println(e.getF4());
System.out.println("===========================================");
}
}
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/
* prototype的scope bean
*
* @author lzlg
* 2023/3/10 19:08
*/
@Component
@Scope("prototype")
public class F1 {
}
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
/
* prototype的scope bean
*
* @author lzlg
* 2023/3/10 19:08
*/
@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class F2 {
}
/
* prototype的scope bean
*
* @author lzlg
* 2023/3/10 19:08
*/
@Component
@Scope("prototype")
public class F3 {
}
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/
* prototype的scope bean
*
* @author lzlg
* 2023/3/10 19:08
*/
@Component
@Scope("prototype")
public class F4 {
}
需配置编译插件
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>8</source>
<target>8</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<goals>
<!-- use this goal to weave all your main classes -->
<goal>compile</goal>
<!-- use this goal to weave all your test classes -->
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
测试代码:
import org.springframework.stereotype.Service;
/
* 要增强的Service
*
* @author lzlg
* 2023/3/10 19:29
*/
@Service
public class MyService {
public void foo() {
System.out.println("MyService foo()...");
}
public static void handle() {
System.out.println("MyService static handle()...");
}
}
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/
* @author lzlg
* 2023/3/10 19:32
*/
@Aspect
public class MyServiceAop {
@Before("execution(* com.lzlg.study.spring.aop.MyService.foo())")
public void before() {
System.out.println("MyServiceAop before()...");
}
@After("execution(* com.lzlg.study.spring.aop.MyService.handle())")
public void after() {
System.out.println("MyServiceAop before()...");
}
}
/
* @author lzlg
* 2023/3/10 19:33
*/
public class TestAspectAop {
public static void main(String[] args) {
// 通过AspectJ在[编译阶段]修改字节码来实现AOP
// 这样可代理static静态方法和final方法
new MyService().foo();
MyService.handle();
// 通过AspectJ-weaver在[类加载阶段]修改字节码来实现AOP
// 这样也可以代理static静态方法和final方法
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
/
* @author lzlg
* 2023/3/10 21:30
*/
public class TestAsmBytecode {
public static void main(String[] args) throws Exception {
// 有了字节码,可以通过类加载到生成的代理对象的代码
byte[] dump = $Proxy0Dump.dump();
// FileOutputStream fos =new FileOutputStream("$Proxy0.class");
// fos.write(dump, 0, dump.length);
// fos.close();
ClassLoader loader = new ClassLoader() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
return super.defineClass(name, dump, 0, dump.length);
}
};
Class<?> proxyClass = loader.loadClass("com.lzlg.study.spring.proxy.asm.$Proxy0");
Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
// 利用构造器创建实例
Foo proxyFoo = (Foo) constructor.newInstance((InvocationHandler) (proxy, method, arguments) -> {
System.out.println("before....");
Object result = null;
System.out.println("after....");
return result;
});
proxyFoo.foo();
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
/
* 自己实现JDK动态代理
*
* @author lzlg
* 2023/3/10 21:08
*/
public class $Proxy0Template extends Proxy implements Foo {
protected $Proxy0Template(InvocationHandler h) {
super(h);
}
@Override
public void foo() {
try {
this.h.invoke(this, foo, new Object[0]);
return;
// 运行时的异常进行处理
} catch (RuntimeException | Error e) {
throw e;
// 其他异常,转换为UndeclaredThrowableException抛出
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
// 把方法转换为静态成员遍历,不用每次调用都反射生成
static Method foo;
static {
try {
foo = Foo.class.getMethod("foo");
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
}
}
}
/
* 接口
*
* @author lzlg
* 2023/3/10 21:07
*/
public interface Foo {
void foo();
}
import org.springframework.asm.*;
/
* @author lzlg
* 2023/3/10 21:56
*/
public class $Proxy0Dump implements Opcodes {
public static byte[] dump() throws Exception {
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(52, ACC_PUBLIC + ACC_SUPER, "com/lzlg/study/spring/proxy/asm/$Proxy0", null, "java/lang/reflect/Proxy", new String[]{"com/lzlg/study/spring/proxy/asm/Foo"});
cw.visitSource("$Proxy0.java", null);
{
fv = cw.visitField(ACC_STATIC, "foo", "Ljava/lang/reflect/Method;", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/reflect/InvocationHandler;)V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(11, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/Proxy", "<init>", "(Ljava/lang/reflect/InvocationHandler;)V", false);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLineNumber(12, l1);
mv.visitInsn(RETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("this", "Lcom/lzlg/study/spring/proxy/asm/$Proxy0;", null, l0, l2, 0);
mv.visitLocalVariable("h", "Ljava/lang/reflect/InvocationHandler;", null, l0, l2, 1);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "foo", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable");
mv.visitLabel(l0);
mv.visitLineNumber(17, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "com/lzlg/study/spring/proxy/asm/$Proxy0", "h", "Ljava/lang/reflect/InvocationHandler;");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, "com/lzlg/study/spring/proxy/asm/$Proxy0", "foo", "Ljava/lang/reflect/Method;");
mv.visitInsn(ACONST_NULL);
mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/reflect/InvocationHandler", "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
mv.visitLabel(l1);
mv.visitLineNumber(20, l1);
Label l3 = new Label();
mv.visitJumpInsn(GOTO, l3);
mv.visitLabel(l2);
mv.visitLineNumber(18, l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 1);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(19, l4);
mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V", false);
mv.visitInsn(ATHROW);
mv.visitLabel(l3);
mv.visitLineNumber(21, l3);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(RETURN);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitLocalVariable("e", "Ljava/lang/Throwable;", null, l4, l3, 1);
mv.visitLocalVariable("this", "Lcom/lzlg/study/spring/proxy/asm/$Proxy0;", null, l0, l5, 0);
mv.visitMaxs(4, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NoSuchMethodException");
mv.visitLabel(l0);
mv.visitLineNumber(26, l0);
mv.visitLdcInsn(Type.getType("Lcom/lzlg/study/spring/proxy/asm/Foo;"));
mv.visitLdcInsn("foo");
mv.visitInsn(ICONST_0);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
mv.visitFieldInsn(PUTSTATIC, "com/lzlg/study/spring/proxy/asm/$Proxy0", "foo", "Ljava/lang/reflect/Method;");
mv.visitLabel(l1);
mv.visitLineNumber(29, l1);
Label l3 = new Label();
mv.visitJumpInsn(GOTO, l3);
mv.visitLabel(l2);
mv.visitLineNumber(27, l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/NoSuchMethodException"});
mv.visitVarInsn(ASTORE, 0);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(28, l4);
mv.visitTypeInsn(NEW, "java/lang/NoSuchMethodError");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/NoSuchMethodException", "getMessage", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoSuchMethodError", "<init>", "(Ljava/lang/String;)V", false);
mv.visitInsn(ATHROW);
mv.visitLabel(l3);
mv.visitLineNumber(30, l3);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(RETURN);
mv.visitLocalVariable("e", "Ljava/lang/NoSuchMethodException;", null, l4, l3, 0);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
}
import java.io.IOException;
import java.lang.reflect.Proxy;
/
* JDK动态代理,目前只能代理接口
*
* @author lzlg
* 2023/3/10 20:09
*/
public class JdkProxyDemo {
interface Foo {
void foo();
}
static class Target implements Foo {
@Override
public void foo() {
System.out.println("target foo()...");
}
}
public static void main(String[] args) {
// 创建代理目标对象
Target target = new Target();
// 生成代理实例
Foo proxy = (Foo) Proxy.newProxyInstance(JdkProxyDemo.class.getClassLoader(),
new Class[]{Foo.class}, (p, method, args1) -> {
System.out.println("before...");
Object result = method.invoke(target, args);
System.out.println("after...");
return result;
});
proxy.foo();
System.out.println(proxy.getClass());
try {
System.in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/
* CGLIB代理
*
* @author lzlg
* 2023/3/10 20:21
*/
public class CglibProxyDemo {
static class Target {
public void foo() {
System.out.println("target foo()...");
}
}
public static void main(String[] args) {
// 代理目标,Target不能是final类,否则生成不了代理的子类
Target target = new Target();
// 创建代理
Target proxy = (Target) Enhancer.create(Target.class, new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
// Object result = method.invoke(target, args);// 使用反射调用,需要目标对象
// Object result = methodProxy.invoke(target, args);// 非反射调用,需要目标对象,Spring中使用的
Object result = methodProxy.invokeSuper(proxy, args);// 非反射调用,无须目标对象
System.out.println("after...");
return result;
}
});
// 代理的方法不能是final方法,否则只会调用目标对象中的方法
proxy.foo();
}
}
自己模拟实现JDK和CGLIB的动态代理:
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/
* 测试
*
* @author lzlg
* 2023/3/11 18:22
*/
public class CglibProxyTest {
public static void main(String[] args) {
// 代理目标对象
Target target = new Target();
Proxy proxy = new Proxy();
proxy.setMethodInterceptor(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
// 反射调用,需要目标对象
// return method.invoke(target, args);
// 非反射调用,使用MethodProxy,需要目标对象
// return methodProxy.invoke(target, args);
// 非反射调用,使用MethodProxy,需要代理对象
return methodProxy.invokeSuper(proxy, args);
}
});
proxy.save();
proxy.save(1);
proxy.save(2L);
}
}
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
/
* 代理对象是代理目标的子类
*
* @author lzlg
* 2023/3/11 18:22
*/
public class Proxy extends Target {
private MethodInterceptor methodInterceptor;
public void setMethodInterceptor(MethodInterceptor methodInterceptor) {
this.methodInterceptor = methodInterceptor;
}
static Method save0;
static Method save1;
static Method save2;
static {
try {
save0 = Target.class.getMethod("save");
save1 = Target.class.getMethod("save", int.class);
save2 = Target.class.getMethod("save", long.class);
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
}
}
// MethodProxy是方法代理,生成和代理的方法相同数量的代理方法
public void saveSuper() {
super.save();
}
public void saveSuper(int i) {
super.save(i);
}
public void saveSuper(long j) {
super.save(j);
}
static MethodProxy save0Proxy;
static MethodProxy save1Proxy;
static MethodProxy save2Proxy;
static {
// 方法代理创建: 目标类, 代理类, 代理方法标识符, 目标类方法, 代理类方法
save0Proxy = MethodProxy.create(Target.class, Proxy.class, "()V", "save", "saveSuper");
save1Proxy = MethodProxy.create(Target.class, Proxy.class, "(I)V", "save", "saveSuper");
save2Proxy = MethodProxy.create(Target.class, Proxy.class, "(J)V", "save", "saveSuper");
}
@Override
public void save() {
try {
methodInterceptor.intercept(this, save0, new Object[0], save0Proxy);
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
@Override
public void save(int i) {
try {
methodInterceptor.intercept(this, save1, new Object[]{i}, save1Proxy);
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
@Override
public void save(long j) {
try {
methodInterceptor.intercept(this, save2, new Object[]{j}, save2Proxy);
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
}
/
* 代理目标对象
*
* @author lzlg
* 2023/3/11 18:22
*/
public class Target {
public void save() {
System.out.println("Target save()...");
}
public void save(int i) {
System.out.println("Target save(int i)...");
}
public void save(long j) {
============ System.out.println("Target save(long j)...");
}
}
=================================================================
import java.lang.reflect.Method;
/
* 测试自己实现的代理
*
* @author lzlg
* 2023/3/10 21:14
*/
public class TestMyProxy {
public static void main(String[] args) {
Target target = new Target();
Foo proxy = new $MyProxy0(new MyInvokeHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before...");
Object result = method.invoke(target, args);
System.out.println("after...");
return result;
}
});
proxy.foo();
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
proxy.bar();
}
}
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
/
* 自己实现JDK动态代理
*
* @author lzlg
* 2023/3/10 21:08
*/
public class $MyProxy0 implements Foo {
private MyInvokeHandler handler;
public $MyProxy0(MyInvokeHandler handler) {
this.handler = handler;
}
@Override
public void foo() {
// 通过一个个调用目标的方法,代码逻辑不一致
// System.out.println("$Proxy0 before foo()");
// new Target().foo();
try {
// foo.invoke(new Target(), new Object[0]);
handler.invoke(this, foo, new Object[0]);
// 运行时的异常进行处理
} catch (RuntimeException | Error e) {
throw e;
// 其他异常,转换为UndeclaredThrowableException抛出
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
@Override
public int bar() {
try {
// foo.invoke(new Target(), new Object[0]);
return (int) handler.invoke(this, bar, new Object[0]);
// 运行时的异常进行处理
} catch (RuntimeException | Error e) {
throw e;
// 其他异常,转换为UndeclaredThrowableException抛出
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
// 把方法转换为静态成员遍历,不用每次调用都反射生成
static Method foo;
static Method bar;
static {
try {
foo = Foo.class.getMethod("foo");
bar = Foo.class.getMethod("bar");
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
}
}
}
/
* 接口
*
* @author lzlg
* 2023/3/10 21:07
*/
public interface Foo {
void foo();
int bar();
}
import java.lang.reflect.Method;
/
* 自己实现动态代理,封装方法调用
*
* @author lzlg
* 2023/3/10 21:09
*/
public interface MyInvokeHandler {
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
/
* 目标类
*
* @author lzlg
* 2023/3/10 21:07
*/
public class Target implements Foo {
@Override
public void foo() {
System.out.println("Target foo()...");
}
@Override
public int bar() {
System.out.println("Target bar()... return 233");
return 233;
}
}
import org.springframework.aop.framework.Advised;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.lang.reflect.Method;
/
* 测试Spring代理增强的特点
* 1.代理对象和原始对象的数据不共用,需要通过代理对象的方法才能访问到原始对象中的数据
* 2.原始对象的private(私有), static(静态), final(不能继承)的方法不能被代理增强
*
* @author lzlg
* 2023/4/9 19:46
*/
@SpringBootApplication
public class TestSpringProxyFeature {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestSpringProxyFeature.class, args);
// 被增强的Bean,通过getBean方法返回的是代理
Bean1 proxy = context.getBean(Bean1.class);
System.out.println(proxy);
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 可发现代理对象中成员变量bean2为null和initialized为false
// 原对象中的成员变量bean2不为null且initialized为true
showProxy(proxy);
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 只有普通的成员方法m1被增强了
proxy.m1();
proxy.m2();
proxy.m3();
Method m4 = Bean1.class.getDeclaredMethod("m4");
m4.setAccessible(true);
m4.invoke(proxy);
context.close();
}
private static void showProxy(Bean1 proxy) throws Exception {
System.out.println("代理中的成员变量: >>>>>>>>>");
System.out.println("bean2 == " + proxy.bean2);
System.out.println("initialized == " + proxy.initialized);
if (proxy instanceof Advised) {
Advised advised = (Advised) proxy;
Bean1 target = (Bean1) advised.getTargetSource().getTarget();
System.out.println("原对象中的成员变量: >>>>>>>>>");
System.out.println("bean2 == " + target.bean2);
System.out.println("initialized == " + target.initialized);
}
}
}
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
/
* 测试Spring中的代理
*
* @author lzlg
* 2023/3/11 19:26
*/
public class TestSpringProxy {
public static void main(String[] args) {
// 1.创建切点
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* foo())");
// 2.创建通知
MethodInterceptor advice = invocation -> {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
};
// 3.创建advisor
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
// 4.创建代理
// 使用JDK代理还是使用CGLIB代理
// proxyTargetClass是ProxyFactory中的一个属性,从public class ProxyConfig中继承的
// a.如果proxyTargetClass为true,则使用CGLIB代理
// b.如果proxyTargetClass为false,且设置了实现的接口信息,用JDK代理
// c.如果proxyTargetClass为false,没有设置实现的接口信息,用CGLIB代理
// FirstTarget target = new FirstTarget();
TwoTarget target = new TwoTarget();
ProxyFactory factory = new ProxyFactory();
factory.setTarget(target);
factory.setInterfaces(target.getClass().getInterfaces());
factory.addAdvisor(advisor);
// T proxy = (T) factory.getProxy();
TwoTarget proxy = (TwoTarget) factory.getProxy();
System.out.println(proxy.getClass());
proxy.foo();
System.out.println("===================");
proxy.bar();
}
interface T {
void foo();
void bar();
}
static class FirstTarget implements T {
@Override
public void foo() {
System.out.println("FirstTarget foo()...");
}
@Override
public void bar() {
System.out.println("FirstTarget bar()...");
}
}
static class TwoTarget {
public void foo() {
System.out.println("TwoTarget foo()...");
}
public void bar() {
System.out.println("TwoTarget foo()...");
}
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/
* @author lzlg
* 2023/4/9 19:50
*/
@Component
public class Bean1 {
Bean2 bean2;
boolean initialized;
/
* 依赖注入
*/
@Autowired
public void setBean2(Bean2 bean2) {
System.out.println(">>>>> Bean1 @Autowired....");
this.bean2 = bean2;
}
public Bean2 getBean2() {
return bean2;
}
public boolean isInitialized() {
return initialized;
}
/
* 初始化方法
*/
@PostConstruct
public void init() {
System.out.println(">>>>> Bean1 init()....");
this.initialized = true;
}
public void m1() {
System.out.println("Bean1 normal m1()...");
}
public final void m2() {
System.out.println("Bean1 final m2()...");
}
public static void m3() {
System.out.println("Bean1 static m3()...");
}
private void m4() {
System.out.println("Bean1 private m4()...");
}
}
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/
* @author lzlg
* 2023/4/9 19:51
*/
@Aspect
@Component
public class Bean1Aspect {
/
* 对Bean1的所有方法进行增强
*/
@Before("execution(* com.lzlg.study.spring.proxy.spring.Bean1.*(..))")
public void before() {
System.out.println("Bean1Aspect >>>>> before...");
}
}
import org.springframework.stereotype.Component;
/
* @author lzlg
* 2023/4/9 19:50
*/
@Component
public class Bean2 {
}
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.*;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
;
/
* 测试Spring中切面通知
*
* @author lzlg
* 2023/3/11 20:26
*/
public class TestSpringAdvisor {
public static void main(String[] args) throws Throwable {
// 创建Aspect的实例工厂对象
AspectInstanceFactory factory = new SingletonAspectInstanceFactory(new AspectOne());
List<Advisor> advisors = new ArrayList<>();
// 模拟解析Aspect切面转换为Advisor切面
for (Method method : AspectOne.class.getDeclaredMethods()) {
// 解析@Before前置通知
if (method.isAnnotationPresent(Before.class)) {
Before before = method.getAnnotation(Before.class);
// 1.切点
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(before.value());
// 2.advice通知
AspectJMethodBeforeAdvice beforeAdvice = new AspectJMethodBeforeAdvice(method, pointcut, factory);
// 3.advisor
Advisor advisor = new DefaultPointcutAdvisor(pointcut, beforeAdvice);
advisors.add(advisor);
// 解析@After后置通知
} else if (method.isAnnotationPresent(After.class)) {
After after = method.getAnnotation(After.class);
// 1.切点
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(after.value());
// 2.advice通知
AspectJAfterAdvice afterAdvice = new AspectJAfterAdvice(method, pointcut, factory);
// 3.advisor
Advisor advisor = new DefaultPointcutAdvisor(pointcut, afterAdvice);
advisors.add(advisor);
}
}
for (Advisor advisor : advisors) {
System.out.println(advisor);
}
System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
FirstTarget target = new FirstTarget();
// 所有的通知都适配成环绕通知进行调用,环绕通知都实现了MethodInterceptor接口,使用了适配器模式
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
// 通过ExposeInvocationInterceptor这个通知才能暴露MethodInvocation到当前执行线程
proxyFactory.addAdvice(ExposeInvocationInterceptor.INSTANCE);
proxyFactory.addAdvisors(advisors);
// 得到所有的封装完成的通知信息
List<Object> adviceList = proxyFactory.getInterceptorsAndDynamicInterceptionAdvice(
FirstTarget.class.getMethod("foo"), FirstTarget.class);
for (Object advice : adviceList) {
// 可以看到AspectJAfterAdvice转换成了MethodBeforeAdviceInterceptor
System.out.println(advice);
}
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 执行调用链
MethodInvocation invocation = new ReflectiveMethodInvocation(
null, target, FirstTarget.class.getMethod("foo"), new Object[0], FirstTarget.class, adviceList
) {
};
invocation.proceed();
}
private static void testAspectJPostCreator() {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("aspectOne", AspectOne.class);
context.registerBean("config", Config.class);
context.registerBean(ConfigurationClassPostProcessor.class);
// 处理切面的bean后置处理器,在创建后依赖注入之前执行
// 在初始化之后执行
context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class);
context.refresh();
// String[] beanDefinitionNames = context.getBeanDefinitionNames();
// for (String beanDefinitionName : beanDefinitionNames) {
// System.out.println(beanDefinitionName);
// }
// AnnotationAwareAspectJAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
context.close();
}
static class FirstTarget {
public void foo() {
System.out.println("FirstTarget foo()...");
}
}
static class TwoTarget {
public void bar() {
System.out.println("TwoTarget bar()...");
}
}
// 高级切面AspectJ
@Aspect
static class AspectOne {
@Before("execution(* foo())")
public void before() {
System.out.println("AspectOne before...");
}
@After("execution(* foo())")
public void after() {
System.out.println("AspectOne after...");
}
}
@Configuration
static class Config {
// 低级切面Advisor
@Bean
public Advisor advisor3(MethodInterceptor advice3) {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* foo())");
return new DefaultPointcutAdvisor(pointcut, advice3);
}
@Bean
public MethodInterceptor advice3() {
return invocation -> {
System.out.println("advice3 before...");
Object result = invocation.proceed();
System.out.println("advice3 after...");
return result;
};
}
}
}
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import java.lang.reflect.Field;
import java.util.List;
/
* 测试Spring中的动态通知
*
* @author lzlg
* 2023/3/15 19:45
*/
public class TestSpringDynamicAdvice {
static class Target {
public void foo(int x) {
System.out.println("Target foo(x=" + x + ")...");
}
}
@Aspect
static class MyAspect {
// 静态通知,无参数绑定,执行时无须使用切点,性能较高
@Before("execution(* foo())")
public void before1() {
System.out.println("MyAspect static before()...");
}
// 动态通知,有参数绑定,执行时需使用切点,性能较差
@Before("execution(* foo()) && args(x)")
public void before2(int x) {
System.out.println("MyAspect dynamic before(x=" + x + ")...");
}
}
@Configuration
static class MyConfig {
@Bean
AnnotationAwareAspectJAutoProxyCreator proxyCreator() {
return new AnnotationAwareAspectJAutoProxyCreator();
}
@Bean
public MyAspect myAspect() {
return new MyAspect();
}
}
public static void main(String[] args) throws Throwable {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(ConfigurationClassPostProcessor.class);
context.registerBean(MyConfig.class);
context.refresh();
AbstractAdvisorAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
List<Advisor> advisors = (List<Advisor>) AbstractAdvisorAutoProxyCreator.class
.getMethod("findEligibleAdvisors", Class.class, String.class)
.invoke(creator, Target.class, "target");
Target target = new Target();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvisors(advisors);
proxyFactory.getProxy();
List<Object> adviceLst = proxyFactory.getInterceptorsAndDynamicInterceptionAdvice(
Target.class.getMethod("foo", int.class), Target.class);
for (Object o : adviceLst) {
System.out.println(o);
}
}
public static void showDetail(Object o) {
try {
Class<?> clazz = Class.forName("org.springframework.aop.framework.InterceptorAndDynamicMethodMatcher");
if (clazz.isInstance(o)) {
Field methodMatcher = clazz.getDeclaredField("methodMatcher");
methodMatcher.setAccessible(true);
Field methodInterceptor = clazz.getDeclaredField("interceptor");
methodInterceptor.setAccessible(true);
System.out.println("环绕通知和切点:" + o);
System.out.println("\t切点为:" + methodMatcher.get(o));
System.out.println("\t通知为:" + methodInterceptor.get(o));
} else {
System.out.println("普通环绕通知:" + o);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
/
* 测试Spring中通知调用链
*
* @author lzlg
* 2023/3/15 19:18
*/
public class TestSpringInvocation {
// 目标类
static class Target {
public void foo() {
System.out.println("Target foo()...");
}
}
// 第一个环绕通知
static class FirstAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("FirstAdvice before...");
Object result = invocation.proceed();
System.out.println("FirstAdvice after...");
return result;
}
}
// 第二个环绕通知
static class SecondAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("SecondAdvice before...");
Object result = invocation.proceed();
System.out.println("SecondAdvice after...");
return result;
}
}
// 自己实现的调用链
static class MyInvocation implements MethodInvocation {
// 目标
private Object target;
// 代理方法(被环绕的方法)
private Method method;
// 代理方法的参数数组
private Object[] args;
// 环绕通知列表
private List<MethodInterceptor> methodInterceptorList;
// 调用计数器
private int counter;
public MyInvocation(Object target, Method method, Object[] args, List<MethodInterceptor> methodInterceptorList) {
this.target = target;
this.method = method;
this.args = args;
this.methodInterceptorList = methodInterceptorList;
this.counter = 1;
}
@Override
public Method getMethod() {
// 获取被代理方法
return method;
}
@Override
public Object[] getArguments() {
// 获取方法参数
return args;
}
@Override
public Object proceed() throws Throwable {
// 如果调用次数已经超过环绕通知列表的数量,则应调用目标方法了
if (counter > methodInterceptorList.size()) {
return method.invoke(target, args);
}
// 递归调用环绕通知,计数器+1
MethodInterceptor interceptor = methodInterceptorList.get(counter++ - 1);
return interceptor.invoke(this);
}
@Override
public Object getThis() {
// 目标对象
return target;
}
@Override
public AccessibleObject getStaticPart() {
return method;
}
}
public static void main(String[] args) throws Throwable {
Target target = new Target();
List<MethodInterceptor> methodInterceptorList = Arrays.asList(
new FirstAdvice(),
new SecondAdvice()
);
// 这里体现了职责链的设计模式
MyInvocation invocation = new MyInvocation(target, Target.class.getMethod("foo"),
new Object[0], methodInterceptorList);
invocation.proceed();
}
}
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Method;
/
* 测试Spring中的切点
*
* @author lzlg
* 2023/3/11 19:51
*/
public class TestSpringPointCut {
public static void main(String[] args) throws Exception {
// 1.使用AspectJ的表达式的切点
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* foo())");
System.out.println("T1 match foo()? " + pointcut.matches(T1.class.getMethod("foo"), T1.class));
System.out.println("T1 match bar()? " + pointcut.matches(T1.class.getMethod("bar"), T1.class));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>.");
// 2.使用@annotation指定注解的切点,但只能匹配方法上的@Transactional注解
AspectJExpressionPointcut annotationPointCut = new AspectJExpressionPointcut();
annotationPointCut.setExpression("@annotation(org.springframework.transaction.annotation.Transactional)");
System.out.println("T1 match foo()? " + annotationPointCut.matches(T1.class.getMethod("foo"), T1.class));
System.out.println("T1 match bar()? " + annotationPointCut.matches(T1.class.getMethod("bar"), T1.class));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>.");
// 3.可匹配类和接口上@Transactional注解的切点
StaticMethodMatcherPointcut matcherPointcut = new StaticMethodMatcherPointcut() {
// 自定义切点匹配逻辑
@Override
public boolean matches(Method method, Class<?> targetClass) {
// 检查方法上是否有@Transactional注解
MergedAnnotations annotations = MergedAnnotations.from(method);
if (annotations.isPresent(Transactional.class)) {
return true;
}
// 检查类上是否有@Transactional注解
// annotations = MergedAnnotations.from(targetClass);
// if (annotations.isPresent(Transactional.class)) {
// return true;
// }
// 检查类的接口和本类上是否有@Transactional注解
annotations = MergedAnnotations.from(targetClass, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY);
if (annotations.isPresent(Transactional.class)) {
return true;
}
return false;
}
};
System.out.println("T1 match foo()? " + matcherPointcut.matches(T1.class.getMethod("foo"), T1.class));
System.out.println("T1 match bar()? " + matcherPointcut.matches(T1.class.getMethod("bar"), T1.class));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>.");
System.out.println("T2 match foo()? " + matcherPointcut.matches(T2.class.getMethod("foo"), T2.class));
System.out.println("T2 match bar()? " + matcherPointcut.matches(T2.class.getMethod("bar"), T2.class));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>.");
System.out.println("T3 match foo()? " + matcherPointcut.matches(T3.class.getMethod("foo"), T3.class));
System.out.println("T3 match bar()? " + matcherPointcut.matches(T3.class.getMethod("bar"), T3.class));
}
static class T1 {
@Transactional
public void foo() {
}
public void bar() {
}
}
@Transactional
static class T2 {
public void foo() {
}
public void bar() {
}
}
@Transactional
interface I {
void foo();
void bar();
}
static class T3 implements I {
@Override
public void foo() {
}
@Override
public void bar() {
}
}
}