简介
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态同意添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一个实现。
主要可以应用在日志记录、性能统计、安全控制、事务处理、异常处理等等。意图为将日志记录、性能统计、安全控制、事务处理、异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
AOP在Spring中得到了丰富支持,应用对象只实现它们应该做的——完成业务逻辑,仅此而已。它们并不负责(甚至是意识)其他的系统级关注点,例如日志或事物支持。
有了这些,我对此的理解为:一个好的系统进行设计,可以让码农做出完美的系统。他们不需要考虑事务,不需要考虑日志,不需要考虑安全,不需要考虑性能,只是关注自己实现的那一部分业务逻辑即可。
那么AOP和OOP又有什么区别和联系呢?
可以说AOP是对OOP一个很好的补充。我们平时编程的过程中,难免会遇到一些代码,这些代码我们无法抽象成一个父类或者方法,因为他们分布在每个类的角落、每个类的边边角角。
在软件开发中,我觉得最重要的思想就是:面对写了3遍以上的代码,一定要考虑是否可以将其进行抽象,当我们再复制粘贴的时候,我们就已经失去了思考。
正是因为这种思想,所以不断有新的名词涌进我们的视野,从面相过程到面相对象,再到现在的面相切面,这些名词的出现,没有一个不使得我们的代码一步步的在减少,相反的就是系统复杂度高了。一个功能不再是只有一个模块就可以完成,往往需要调用好几个类才可以完成一个功能。实现了由一体式房屋到搭积木式房屋的过度。
所以AOP和OOP不是对立的,只是一个很好的补充而已。OOP没有AOP可以做出系统,只是有了之后,代码结构更加清晰。AOP如果缺少了OOP的支持,那么它的存在可以说就没有那么多的价值了
说的这么热闹,那么AOP到底应该如何进行开发呢?
1.发现切面,也称关注点,这也是最最关键的,发现的窍门就是查找你那重复了不只3便的代码吧。
2.实现关注点,简单的说就是将你那重复了不只3便的代码同意放到一个类里。
3.组合关注点,就是确定在什么时候执行关注点。例如你关注点里有3个动作,这3个动作分别是在某个方法的执行成功、失败、异常执行的,那么只需要简单的配置一下即可。
下面通过一个示例来进一步说明一下如何开发AOP(分别通过注解和配置文件来实现)
接口和实现类:
public interface UserManager {
public void addUser(String username,String password);
}
public class UserManagerImpl implements UserManager {
@Override
public void addUser(String username, String password) {
System.out.println("UserManagerImpl.addUser()");
}
}
采用注解方式实现:
@Aspect //发现切面
public class SecurityHandler {
/**
* 定义Pointcut,Pointcut的名称为addAddMethod(),此方法没有返回值和参数
* 该方法就是一个标识,不进行调用
*/
@Pointcut("execution(* add*(..))") //组合关注点
private void addAddMethod(){};
/**
* 定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上
*/
@Before("addAddMethod()") //组合关注点
//@After("addAddMethod()")
private void checkSecurity() { //实现关注点
System.out.println("-------checkSecurity-------");
}
}
采用配置文件方式实现(将上述类中的注解、addAddMethod方法去掉,在applicationContext.xml中进行配置):
<!-- 声明使得在程序可以认识关于AOP的注解 -->
<aop:aspectj-autoproxy />
<bean id="userManager" class="com.jianxin.spring.UserManagerImpl" />
<bean id="securityHandler" class="com.jianxin.spring.SecurityHandler"/>
<aop:config>
<aop:aspect id="securityAspect" ref="securityHandler">
<aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>
<aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>
</aop:aspect>
</aop:config>
测试程序
public class Client {
public static void main(String[] args) {
BeanFactory factory=new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager=(UserManager)factory.getBean("userManager");
userManager.addUser("张三", "123");
}
}
至此,示例就完成了,最后再说一下,有了AOP,OOP显得更加完美。AOP做的更多的是服务性的工作,OOP做的是主要工作。