Spring,AOP,基于代理类的AOP实现,ProxyFactoryBean

Spring中代理对象可通过XML配置方式获得,也可通过ProxyFactory手动编程方式创建对象。Spring中的代理对象其实是JDK Proxy和CGLIB Proxy 的结合。
一、创建接口

package com.itheima.jdk;

public interface UserDao {
    public void addUser();

    public void deleteUser();
}

二、创建实现类

package com.itheima.jdk;

public class UserDaoImpl implements UserDao {
    public void addUser() {
        System.out.println("添加用户");
    }

    public void deleteUser() {
        System.out.println("删除用户");
    }
}

三、创建切面类

需要实现org.aopalliance.intercept.MethodInterceptor接口,并实现接口中的invoke()方法。

package com.itheima.factorybean;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
// 切面类
public class MyAspect implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        check_Permissions();
        // 执行目标方法
        Object obj = mi.proceed();
        log();
        return obj;
    }
    public void check_Permissions(){
        System.out.println("模拟检查权限...");
    }
    public void log(){
        System.out.println("模拟记录日志...");
    }
}

四、创建配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
    <!-- 1 目标类 -->
    <bean id="userDao" class="com.itheima.jdk.UserDaoImpl" />
    <!-- 2 切面类 -->
    <bean id="myAspect" class="com.itheima.factorybean.MyAspect" />
    <!-- 3 使用Spring代理工厂定义一个名称为userDaoProxy的代理对象 -->
    <bean id="userDaoProxy"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 3.1 指定代理实现的接口 -->
        <property name="proxyInterfaces"
            value="com.itheima.jdk.UserDao" />
        <!-- 3.2 指定目标对象 -->
        <property name="target" ref="userDao" />
        <!-- 3.3 指定切面,织入环绕通知 -->
        <property name="interceptorNames" value="myAspect" />
        <!-- 3.4 指定代理方式,true:使用cglib,false(默认):使用jdk动态代理 -->
        <property name="proxyTargetClass" value="true" />
    </bean>
</beans>

五、创建主程序

package com.itheima.factorybean;
import org.springframework.context.ApplicationContext;
import 
    org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.jdk.UserDao;
// 测试类
public class ProxyFactoryBeanTest {
    public static void main(String args[]) {
       String xmlPath = "com/itheima/factorybean/applicationContext.xml";
       ApplicationContext applicationContext = 
                                 new ClassPathXmlApplicationContext(xmlPath);
       // 从Spring容器获得内容
       UserDao userDao = 
                       (UserDao) applicationContext.getBean("userDaoProxy");
       // 执行方法
       userDao.addUser();
       userDao.deleteUser();
       System.out.println(userDao.getClass().getName());
    }
}

六、运行结果

模拟检查权限...
添加用户
模拟记录日志...
模拟检查权限...
删除用户
模拟记录日志...
com.itheima.jdk.UserDaoImpl$$EnhancerBySpringCGLIB$$89b6e7f3

七、如果修改配置文件,如下:

        <!-- 3.4 指定代理方式,true:使用cglib,false(默认):使用jdk动态代理 -->
        <property name="proxyTargetClass" value="false" />

八、则运行结果变为:

模拟检查权限...
添加用户
模拟记录日志...
模拟检查权限...
删除用户
模拟记录日志...
com.sun.proxy.$Proxy4

本文参考:《Java EE企业级应用开发教程》

posted @ 2021-07-24 08:27  那些年的事儿  阅读(141)  评论(0编辑  收藏  举报