上篇写了AOP-aspectj实现面向切面https://blog.csdn.net/qq_36237165/article/details/101994404,今天使用动态代理实现面向切面
,下面介绍如何使用动态代码实现有点页面需要登录才能跳转过去需要。
1》定义个代理接口
/**
* 定义个代理接口
*/
public interface ILogin {
void toLogin();
}
2》定义个类实现InvocationHandler接口
/**
* 代理 切面类
*/
public class MyLoginProxyHandler implements InvocationHandler {
private Object proxyTag;
private Context context;
public MyLoginProxyHandler(Object proxyTag, Context context) {
this.proxyTag = proxyTag;
this.context = context;
}
/**
* @param proxy
* @param method
* @param args 定义的接口参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object object = null;
//如果登录就执行 代理接口方法,没有就执行else代码
if (MyApp.getInstance().isLogin()) {
//参数(代理接口实现类 ,invoke方法第三个参数args)
//代码执行这里 会回调接口方法
//如果不调用这个方法,接口方法不会回调
//如果你想把数据传递给接口方法--》args[0]="测试";
object = method.invoke(proxyTag, args);
Log.e("zdh","----invoke----登录"+"-------");
} else {
//去登录
context.startActivity(new Intent(context,LoginActivity.class));
Log.e("zdh","-----invoke---没有登录");
}
return object;
}
}
3》需要代理的类,实现代理接口
/**
* 实现代理接口
*/
public class MainActivity extends AppCompatActivity implements ILogin {
private ILogin iLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化 代理接口实例 参数(类加载器,代理接口类,切面类)
iLogin = (ILogin) Proxy.newProxyInstance(getClassLoader(), new Class[]{ILogin.class}, new MyLoginProxyHandler(this, getApplicationContext()));
}
/**
* 用户登录后
* 逻辑代码
*/
@Override
public void toLogin() {
Log.e("zdh","--------toLogin");
startActivity(new Intent(this, TextActivity.class));
}
/**
* 需要使用代理的方法,调用接口方法
* @param view
*/
public void send(View view) {
Log.e("zdh","--------send");
iLogin.toLogin();
}
}
总结:动态代理,是Java自带的,不需要依赖第三方库,但是侵入性比较强。
代理不够优雅。
注意:实现InvocationHandler类的invoke方法,调用object = method.invoke(proxyTag, args);方法把object返回,代理接口方法才被执行,invoke方法参数(实现接口类,args对象)
源码地址:https://github.com/zhudaihao/AOP_Poxy