1、AOP(Aspect Oriented Programming)
面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
面向切面一般指的是横向切面,把需要抽取的相同的业务功能,抽取出来,做成一个切面。如取款机,在取款、查询、转账中都要验证用户,我们就可以把这个验证用户的功能抽取出来,做成一个切面。AOP的本质就是在这一系列的纵向的业务流程中,把那些有相同业务的子流程,抽取出一个横向的面。
2、动态代理(dynamic proxy)
利用Java的反射技术,在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例,代理的是接口,不是类,也不是抽象类。在运行时才知道具体的实现。
JDK动态代理-Proxy.newProxyInstance
//返回某个对象的代理对象
public static Object newProxyInstance(
ClassLoader loader,//用哪个类加载器去加载代理对象
Class<?>[] interfaces,//动态代理类需要实现的接口
InvocationHandler h) //动态代理方法在执行时,会调用h里面的invoke方法去执行
需求:在做数据的增删改操作之前,都需要查询数据,保存数据,这个怎么用AOP的思想来做呢?
public interface DBOperation {
void insert(String s);
void delete();
void update();
// 查询数据,保存数据
void save();
}
public class MainActivity extends Activity implements DBOperation {
private DBOperation db;
private final static String TAG = "TAG";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = (DBOperation) Proxy.newProxyInstance(DBOperation.class.getClassLoader(),
new Class[]{DBOperation.class}, new DBHander(this));
}
class DBHander implements InvocationHandler {
private DBOperation db;
DBHander(DBOperation db) {
this.db = db;
}
/**
* @param proxy 就是代理对象,newProxyInstance方法的返回对象
* @param method 调用的方法
* @param args 方法中的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Log.e(TAG, "method = " + method.getName());
Log.e(TAG, "args = " + Arrays.toString(args));
if (db != null) {
Log.e(TAG, "操作数据库之前,开始备份……");
save(); // 查询数据库后备份,详细过程省略
Log.e(TAG, "数据备份完成,等待操作");
return method.invoke(db, args);
}
return null;
}
}
// 点击事件
public void jump(View view) {
db.insert("1111111");
db.delete();
db.update();
}
@Override
public void insert(String s) {
Log.e(TAG, "新增数据" + s);
}
@Override
public void delete() {
Log.e(TAG, "删除数据");
}
@Override
public void update() {
Log.e(TAG, "修改数据");
}
@Override
public void save() {
Log.e(TAG, "保存数据");
}
}