Java 代理
一、静态代理
接口
public interface TargetInteface {
void method1();
void method2();
int method3(Integer i);
}
接口实现类
public class Target implements TargetInteface {
@Override
public void method1() {
System.out.println("method1 running ...");
}
@Override
public void method2() {
System.out.println("method2 running ...");
}
@Override
public int method3(Integer i) {
System.out.println("method3 running ...");
return i;
}
}
代理类
public class TargetProxy implements TargetInteface {
@Override
public void method1() {
System.out.println("执行方法前...");
new Target().method1();
System.out.println("执行方法后...");
}
@Override
public void method2() {
System.out.println("执行方法前...");
new Target().method2();
System.out.println("执行方法后...");
}
@Override
public int method3(Integer i) {
System.out.println("执行方法前...");
int method3 = new Target().method3(i);
System.out.println("执行方法后...");
return method3;
}
}
测试
public static void main(String[] args) {
TargetInteface target = new TargetProxy();
target.method1();
System.out.println("-----------------------------");
target.method2();
System.out.println("-----------------------------");
System.out.println(target.method3(3));
}
输出
执行方法前...
method1 running ...
执行方法后...
-----------------------------
执行方法前...
method2 running ...
执行方法后...
-----------------------------
执行方法前...
method3 running ...
执行方法后...
3
二、jdk动态代理
除代理类外,其他同静态代理 代理类
public class TargetProxy {
public static <T> Object getTarget(T t) {
return Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行方法前...");
Object invoke = method.invoke(t, args);
System.out.println("执行方法后...");
return invoke;
}
});
}
}
三、cglib代理
当没有接口时采用cglib代理 cglib内部原理是创建了一个子类去继承我们的实体类并重写其中的方法,因此在测试时才用的是父类引用指向子类对象。无论执行那个方法都是找到子类的方法去执行的
依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
实体类
public class Target {
public void method1() {
System.out.println("method1 running ...");
}
public void method2() {
System.out.println("method2 running ...");
}
public int method3(Integer i) {
System.out.println("method3 running ...");
return i;
}
}
代理类
public class TargetProxy {
static <T> Object getProxy(T t) {
Enhancer en = new Enhancer();
en.setSuperclass(t.getClass());
en.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("执行方法前。。。");
Object invoke = methodProxy.invokeSuper(object, args);
System.out.println("执行方法后。。。");
return invoke;
}
});
return en.create();
}
}
测试
public static void main(String[] args) {
Target target = (Target) TargetProxy.getProxy(new Target());
target.method1();
}
执行结果
执行方法前。。。
method1 running ...
执行方法后。。。
四、aop
配置
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="target" class="com.heaboy.aopdemo.aop.Target"/>
<bean id="targetAdvice" class="com.heaboy.aopdemo.aop.TargetAdvice"/>
<bean id="targetProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target"/>
<property name="interceptorNames" value="targetAdvice"/>
<property name="proxyTargetClass" value="true"/>
<property name="interfaces" value="com.heaboy.aopdemo.aop.TargetInteface"/>
</bean>
</beans>
接口和实体同静态代理
增强
public class TargetAdvice implements MethodInterceptor, MethodBeforeAdvice, AfterReturningAdvice {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("前置环绕通知");
Object proceed = methodInvocation.proceed();
System.out.println("后置环绕通知");
return proceed;
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置返回通知");
}
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置通知");
}
}
测试
public class AopTest {
public static void main(String[] args) {
ApplicationContext appCtx = new ClassPathXmlApplicationContext("spring-aop.xml");
Target targetProxy = (Target) appCtx.getBean("targetProxy");
targetProxy.method1();
}
}
输出结果
前置环绕通知
前置通知
method1 running ...
后置返回通知
后置环绕通知
五、通过aop模式获得子类的模式
配置 spring-confaop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="target" class="com.heaboy.aopdemo.confaop.Target"/>
<bean id="targetAspect" class="com.heaboy.aopdemo.confaop.TargetAspect"/>
<aop:config proxy-target-class="true">
<aop:aspect ref="targetAspect">
<aop:pointcut id="pointcut" expression="execution(* com.heaboy.aopdemo.confaop.*.*(..))"/>
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
<aop:around method="around" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
<aop:after-throwing method="afterThrowing" throwing="ex" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
实体类
public class Target {
public void method1() {
System.out.println("method1 running ...");
}
public void method2() {
System.out.println("method2 running ...");
}
public int method3(Integer i) {
System.out.println("method3 running ...");
int i1 = 1 / i;
return i;
}
}
切面类
public class TargetAspect {
public void before() {
System.out.println("conf前置通知");
}
public void after() {
System.out.println("conf后置通知");
}
public void afterReturning() {
System.out.println("conf后置返回通知");
}
public void afterThrowing(Exception ex) throws Exception {
System.out.println("conf异常通知");
System.out.println(ex.getMessage());
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object proceed = null;
if (!"".equals("admin")) {
System.out.println("conf环绕前置");
proceed = pjp.proceed(pjp.getArgs());
System.out.println("conf环绕后置");
}
return proceed;
}
}
测试
public class AopTest {
public static void main(String[] args) {
ApplicationContext appCtx = new ClassPathXmlApplicationContext("spring-confaop.xml");
Target targetProxy = (Target) appCtx.getBean("target");
System.out.println(targetProxy.method3(0));
}
}
输出结果
|