spring aop底层原理ProxyFactoryBean的具体使用过程--FactoryBean深入理解

实际的spring使用aop的过程,配置好ProxyFactoryBean,给ProxyFactoryBean设置一个bean id

然后通过ac.getBean(bean id),就取得被ProxyFactoryBean代理的对象,不是ProxyFactoryBean

因为这个bean id虽然代表ProxyFactoryBean对象,直接getBean获取的是ProxyFactoryBean.getObject()返回的对象,即代理对象

ac.getBean(&bean id),才能取得ProxyFactoryBean对象

【FactoryBean深入理解】

  1. FactoryBean,就是一个bean对象,不要被前面的Factory扰乱误导,也是要放入BeanFactory被spring管理
  2. FactoryBean特殊在,通过常规的ApplicationContext.getBean(beanId) 获取的不是FactoryBean这个直接对象,而是调用FactoryBean.getObject()生成的对象,返回给你
  3. ApplicationContext.getBean(&beanId) ,加上&才能取得FactoryBean这个对象,可以理解为c语言里的取地址的意思
  4. FactoryBean这样的过程,就是为了方便你定义生成【复杂bean】对象,就是这个bean对象不是简单的new ,设置几个参数,还有其他初始化才能完整被使用,比如ProxyFactoryBean

下面是直接使用main方法调用aop,帮助理解spring的aop过程,maven项目

//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dddd</groupId>
    <artifactId>spring</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <spring.version>4.3.3.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.10</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
//ServInter.java  代理接口

package com.dddd.aop;

public interface ServInter {
    public void say();
}

//MyService.java  实现接口

package com.dddd.aop;

import org.springframework.stereotype.Service;

@Service
public class MyService implements ServInter {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void say() {

        System.out.println("MyService say:" + name);
    }
}

//MyBeforeAop.java  定义aop处理方法

package com.dddd.aop;

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
public class MyBeforeAop implements MethodBeforeAdvice {

    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("before aop ["+method.getName()+"] do sth...................");
    }
}
//Test.java  main方法测试

package com.dddd;

import com.dddd.aop.ServInter;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {


    public static void main(String[] args) {


        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("com.dddd");

        //aop3  实际的spring使用aop的过程,配置好ProxyFactoryBean,给ProxyFactoryBean设置一个bean id
        //然后通过ac.getBean(bean id),就取得被ProxyFactoryBean代理的对象,不是ProxyFactoryBean
        //因为这个bean id虽然代表ProxyFactoryBean对象,直接getBean获取的是ProxyFactoryBean.getObject()返回的对象,即代理对象
        //ac.getBean(&bean id),才能取得ProxyFactoryBean对象

        ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
        proxyFactoryBean.setBeanFactory(ac.getBeanFactory());
        //aop拦截处理类
        proxyFactoryBean.setInterceptorNames("myBeforeAop");
        //代理的接口
        proxyFactoryBean.setInterfaces(ServInter.class);
        //被代理对象
        proxyFactoryBean.setTarget(ac.getBean(ServInter.class));
        //放入bean工厂,实际开发是在config下使用注解,设置多个proxyFactoryBean代理,设置不同bean id
        ac.getBeanFactory().registerSingleton("myproxy",proxyFactoryBean);

        ServInter servInterProxy = (ServInter) ac.getBean("myproxy");
        servInterProxy.say();
        //获取直接的ProxyFactoryBean对象,加&
        System.out.println(ac.getBean("&myproxy"));
    }
}
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Spring AOP (Aspect Oriented Programming) 是 Spring 框架中的一个模块,它实现了面向切面编程,允许开发者将横切关注点(如事务管理、日志记录、安全检查等)抽取到独立的模块中,从而避免代码重复和提高模块的可维护性。Spring AOP底层原理主要基于以下几个关键概念: 1. **通知(Advice)**: 是 AOP 的核心,它是对目标方法执行前后的行为进行增强的代码片段。Spring 提供了五种类型的通知:前置通知(Before)、后置通知(After)、返回后通知(AfterReturning)、异常通知(AfterThrowing)和最终通知(Around)。 2. **切点(Pointcut)**: 定义了一组相关的通知应该何时何地应用。Spring 使用表达式语言(如`@annotation`, `@execution`, `@target`, `@within`等)来定义切点,匹配方法执行的条件。 3. **连接点(Join Point)**: 是程序执行过程中的一点,是通知被应用的地方。Spring AOP 检查通知的匹配条件并在合适的时候执行。 4. **代理(AOP Proxy)**: Spring AOP 实现了一种特殊的代理机制,为被拦截的目标对象创建一个代理对象。有两种代理模式:JDK 动态代理和 CGLIB 生成的字节码代理。对于接口,使用 JDK 动态代理;对于类,如果目标类没有实现接口或没有 final 方法,使用 CGLIB。 5. **切面(Angle)**: 是一组相关通知的集合,由切点和通知组成。在 Spring 中,切面通过 `@Aspect` 注解声明,`@AspectJ` 是其底层语法支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值