Spring代理的特点

一.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>
相关推荐
一直_在路上17 小时前
Go架构师实战:玩转缓存,击破医疗IT百万QPS与“三大天灾
前端·面试
早八睡不醒午觉睡不够的程序猿17 小时前
Vue DevTools 调试提示
前端·javascript·vue.js
恋猫de小郭17 小时前
基于 Dart 的 Terminal UI ,pixel_prompt 这个 TUI 库了解下
android·前端·flutter
天天向上102417 小时前
vue el-form 自定义校验, 校验用户名调接口查重
前端·javascript·vue.js
一 乐18 小时前
智慧外贸平台|基于Java+vue的智慧外贸平台系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·外贸服务系统
忧郁的蛋~18 小时前
前端实现网页水印防移除的实战方案
前端
喝奶茶的Blair18 小时前
PHP应用-组件框架&前端模版渲染&三方插件&富文本编辑器&CVE审计(2024小迪安全DAY30笔记)
前端·安全·php
浪潮行舟18 小时前
WebGIS:在 Vue 2 项目中使用 Mapbox 时,如果需要加载的 GIS 数据量过大,怎么让接口一次性获取的geojson数据分批加载
前端·javascript·vue.js
一叶飘零_sweeeet18 小时前
打造高可用系统通知架构:站内信、短信、邮件、推送全方案解析
java·系统通知
SimonKing18 小时前
🐔老乡鸡把菜谱在GitHub开源了,还说要给程序员发会员卡
java·后端·程序员