大纲如下:
AOP 是什么?
AOP 是一种技术,只存在web服务端么?
AOP 与OOP 的关系以及存在价值?
AOP和代理的关系,同时代理都有哪些形式?
代理形式的对比
Aspectj是什么
Aspectj的优点 缺点
Aspectj 语法详解以及使用
AOP 是什么?
AOP Aspectj Oriented Programming 直译过来就是面向切面编程,通俗的讲也叫”函数式编程”,它通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
AOP 是一种技术,只存在web服务端么?
首先来说AOP它不仅仅是一项技术,更多的可以认为它是一种思想,在这个思想之上通过一系列的技术手段是来达到这种效果。我们使用这种思想或者技术大多实在web服务端,尤其是在使用spring框架对事物进行管理的时候,当然它不是项只能使用与服务端的技术,在终端也有他的表现使用价值,但是由于终端在业务复杂度上面不如web的复杂度高(个别终端应用除外),所以一直不是很流行或者讲没有流行起来。
AOP 与OOP 的关系以及存在价值?
肯定的讲AOP是OOP的延续,开始已经说了“函数式编程”,站在“万物皆对象”的角度看,函数本身就是对象,不信你回忆一下java.lang.reflect.Method,method本身就是对象,在某种意义上aop更像是对oop的补强。它存在的价值就体现在oop办不到或者要费时费力才能办到,它能轻轻松松完成这一点上,比如:权限认证;日志管理; 事务管理等,在终端我们可以根据业务来自己划分,我自己项目里面更多的是小功能的实现比如:动态权限申请,日志记录,函数执行流程等
AOP和代理的关系,同时代理都有哪些形式?
可以这样讲AOP的具体实现就是代理模式的另一种体现。
谈到代理我们得区分一下代理的形式:
从代理对象生成的角度来看我们分为:静态代理和动态代理
再细化代理对象的生命周期我们动态代理分为:编译期生成和运行时生成
代理形式的对比
提到代理我们不得不提一下几种技术
静态代理
动态代理
cglib
aspectj
开始详细讲解和对比以上技术之前我们要弄清楚代理定义,代理的特点有哪些?第一:持有目标对象,第二:隐藏目标的真实实现。通俗的讲就是:为其他对象提供一种代理以控制对这个对象的访问。
那么他们各有什么优点和缺点呢?以及我们要在终端使用应该选择哪一种技术呢?
首先来看静态代理:
先定义一个接口:
public interface IService {
User queryUserInfo();
double queryBalance();
} //user 对象这里不给出代码了
定义真是实现类:
public class ServiceImpl implements IService{
public User queryUserInfo() {
System.out.println("真实对象mock user info-----------查询前");
User user = new User();
user.setAge(10);
user.setName("小明");
user.setGender(1);
return user;
}
public double queryBalance() {
System.out.println("真实对象mock query balance");
return 10000.00;
}
}
这个时候我们定义一个调用对象去调用真实实现:
public class Admin {
public void realQuery(){
IService service = new ServiceImpl();
User user = service.queryUserInfo();
System.out.println(user.toString());
}
public void proxyQuery(){
IService service = new ServiceImplProxy(true);
User user = service.queryUserInfo();
System.out.println(user.toString());
}
public static void main(String[] args) {
Admin admin = new Admin();
admin.realQuery();
}
}
运行一下,结果正常。但是我们忽然发现在查询前(queryUserInfo())要去判断当前用户是否已经登录或者有其他条件,这个时候我们发现ServiceImpl 这个对象的queryUserInfo函数要被修改了,需要添加其他逻辑,但是设计原则里面的"开闭原则"还是要遵循的,那么怎么办呢???这个时候我们的代理对象就需要出现了
静态代理类:
public class ServiceImplProxy implements IService{
boolean isLogin;
ServiceImpl service;
public ServiceImplProxy(boolean isLogin){
this(new ServiceImpl(),isLogin);
}
public ServiceImplProxy(ServiceImpl service,boolean isLogin){
this.service = service;
this.isLogin = isLogin;
}
public User queryUserInfo() {
System.out.println("查询用户信息之前");
//这里的isLogin是构造传递的,模拟的是web端从Session里面获取是否已经登录的动作
if(isLogin){
User user = service.queryUserInfo();
System.out.println("查询用户信息之后");
return user;
}else{
System.out.println("未登录用户查询用户信息请注意......");
throw new IllegalStateException("权限不够,查询用户信息出错");
}
}
public double queryBalance() {
return service.queryBalance();
}
}
然后在执行Admin这个文件里面proxyQuery函数,发现功能或者需求也已经实现了(文章内代码的格式,这排版好坑啊,也许是我不会用。。。)
静态代理的好处:遵守了开闭原则,是典型oop的一种体现。 缺点是:需要为每一个目标对象实现一个代理对象,这样会造成我们的class文件很多,如果接口发生变更相关联的代理类都需要修改。
网友评论