Step1
:项目
aop_leadin1
先定义好接口与一个实现类,该实现类中除了要实现接口中的方法外,还要再写两个非
业务方法。非业务方法也称为交叉业务逻辑:
➢ doTransaction():用于事务处理
➢ doLog():用于日志处理
然后,再使接口方法调用它们。接口方法也称为主业务逻辑。
接口:
Step2
:项目
aop_leadin2
当然,也可以有另一种解决方案:将这些交叉业务逻辑代码放到专门的工具类或处理类
中,由主业务逻辑调用。
Step3:项目 aop_leadin3
以上的解决方案,还是存在弊端:交叉业务与主业务深度耦合在一起。当交叉业务逻辑
较多、时,在主业务代码中会出现大量的交叉业务逻辑代码调用语句,大大影响了主业务逻辑
的可读性,降低了代码的可维护性,同时也增加了开发难度。
所以,可以采用动态代理方式。在不修改主业务逻辑的前提下,扩展和增强其功能。
功能增强:
项目结构
项目展示
1.创建SomeService接口
package com.it.service;
public interface SomeService {
void doSome();
void doOther();
}
2.创建SomeServiceImpl实现类
package com.it.service.impl;
import com.it.service.SomeService;
import com.it.util.ServiceTools;
import java.util.Date;
//现在是基本的增加方法中的功能,会改变原有代码的逻辑
//如果使用动态代理,就可以在不修改原来代码的前提下,额外的增加功能。
/**
* 动态代理:在程序执行的过程中,创建代理对象,通过代理对象执行方法,给目标类中的方法增加额外功能。
*/
public class SomeServiceImpl implements SomeService {
@Override
public void doSome() {
System.out.println("执行了业务方法的doSome()");
}
@Override
public void doOther() {
System.out.println("执行了业务方法的doOther()");
}
}
3.创建ServiceTools工具类
package com.it.util;
import java.util.Date;
public class ServiceTools {
public static void doLog(){
System.out.println("当前执行时间为:"+new Date());
}
public static void doCommit(){
System.out.println("提交事务");
}
}
4.创建MyInvocationHandler动态代理类
package com.it.handler;
import com.it.util.ServiceTools;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
// 因为是动态代理,目标对象是活动的,所以定义一个变量用来保存目标
private Object target;//target目标对象,最终会是SomeServiceImpl类
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
// 代理对象在执行方法时,会调用这个invoke()方法。
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("执行了MyInvocationHandler类中的invoke()");
//下面的方法有返回值,要进行一个记录
Object res=null;
ServiceTools.doLog();
// invoke()方法主要是执行目标类中的方法,通过Method类实现
res=method.invoke(target,objects);//SomeServiceImpl.doSome(),doOther();
ServiceTools.doCommit();
// 返回目标方法返回结果
return res;
}
}
5.创建动态代理测试类
package com.it;
import com.it.handler.MyInvocationHandler;
import com.it.service.SomeService;
import com.it.service.impl.SomeServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
// 使用jdk的Proxy创建代理对象
// 首先创建目标对象
SomeService target=new SomeServiceImpl();
// 创建InvocationHandler对象
InvocationHandler handler=new MyInvocationHandler(target);
// 使用Proxy创建对象
/**
* 格式是固定的, newProxyInstance()的第一个参数是目标类的类加载器,
* 第二个参数是目标类实现了那些接口
* 第三个参数是该代理类要执行的功能
*/
//代理的是SomeService接口中的功能,所以要强转一下
SomeService proxy= (SomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler);
// 通过代理执行方法,会调用handler中的invoke()方法
proxy.doSome();
proxy.doOther();
}
}
项目测试结果