一.Spring代理的特点
1.依赖注入和初始化影响的是原始的对象。
2.代理和目标是两个对象,二者成员变量不共用数据。
二.测试
首先准备以下几个类。
Bean1
package com.example.springdemo.demos.a13;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* @author zhou
* @version 1.0
* @description TODO
* @date 2025/8/30 20:33
*/
@Component
public class Bean1 {
private static final Logger log = LoggerFactory.getLogger(Bean1.class);
protected Bean2 bean2;
protected boolean initialized;
@Autowired
public void setBean2(Bean2 bean2){
log.debug("setBean");
this.bean2 = bean2;
}
@PostConstruct
public void init(){
log.debug("init");
initialized = true;
}
public Bean2 getBean2(){
log.debug("getBean2()");
return bean2;
}
public boolean isInitilized(){
log.debug("isInitilized()");
return this.initialized;
}
}
Bean2
package com.example.springdemo.demos.a13;
import org.springframework.stereotype.Component;
/**
* @author zhou
* @version 1.0
* @description TODO
* @date 2025/8/30 20:36
*/
@Component
public class Bean2 {
}
切面类
package com.example.springdemo.demos.a13;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
/**
* @author zhou
* @version 1.0
* @description TODO
* @date 2025/8/30 20:32
*/
@Aspect
@Component
public class MyAspect {
//对所有方法增强
@Before("execution(* com.example.springdemo.demos.a13.Bean1.*(..))")
public void before(){
System.out.println("before");
}
}
TestProxy(测试代理类)
package com.example.springdemo.demos.a13;
import org.springframework.aop.framework.Advised;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author zhou
* @version 1.0
* @description TODO
* @date 2025/8/30 20:41
*/
@SpringBootApplication
public class TestProxy {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestProxy.class, args);
Bean1 proxy = context.getBean(Bean1.class);
proxy.setBean2(new Bean2());
proxy.init();
context.close();
showProxyAndTarget(proxy);
System.out.println(">>>>>>>>>>>>>");
System.out.println(proxy.getBean2());
System.out.println(proxy.isInitilized());
}
public static void showProxyAndTarget(Bean1 proxy) throws Exception{
System.out.println(">>>>>>>>代理中的成员变量");
System.out.println("initialized="+proxy.initialized);
System.out.println("bean2="+proxy.bean2);
if(proxy instanceof Advised){
System.out.println(">>>>>>>>>>>目标中的成员变量");
//获取目标对象
Bean1 target = (Bean1) ((Advised) proxy).getTargetSource().getTarget();
System.out.println(target);
System.out.println("\tinitialized==="+target.initialized);
System.out.println("\tbean2="+target.bean2);
}
}
}
测试结果:

目标对象进行了初始化操作。

代理对象中的成员变量没有被赋值,而目标对象是有值的。并且我们通过代理对象调用方法也可以得到成员变量的值,最后打印bean2对象以及initialized的值。这是因为代理对象调用方法最后走的还是目标对象的方法,所以这两个属性有值。
三.遇到的问题
在测试过程中,控制台并没有打印日志。原因是这是一个新建的案例项目,我们还得配置logback-spring.xml文件,控制日志的输出规则。文件存方在Resources目录下。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 设置日志级别 -->
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
<!-- 针对特定包设置日志级别 -->
<logger name="com.example.springdemo.demos.a13" level="DEBUG" />
</configuration>