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; import org.springframework.stereotype.Repository; // 目标类 @Repository("userDao") 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