无论在那种情况下,以上文描述的方式进行设计都不是个特别好的主意。要注意的是,在上面提及的情况中最常用的对象实际上却是最不重要的对象。Logger对象并没有增加任何额外的业务功能。它只是对实现业务功能的过程提供了一种支持,而在对象交互中它获得的却是最大量的注意力。OOP还不错,但仍需要寻找另外一个层次的模块化思路,以解决对相互交叉的关注点进行更干净的分离问题。
所需软件:
Aspectj编程需要
Spring框架需要
首先安装Java SE和Eclipse。使用下列jar文件在Eclipse中创建用户库并包含如下所列的库。
创建aspectj用户库并导入下列jar文件
1. aopalliance-x.x.x.jar
2. cglib-nodep-x.x.x.jar
3. aspectjrt.jar, aspectjweaver.jar (可能需要解压aspectj-x.x.x.jar才能得到这两个文件)
4. asm-x.x.jar
创建Spring用户库并包含下列jar文件
1. commons-logging-x.x.x.jar
2. spring-framework-x.x.x/dist中所有的jar文件
在Eclipse中完成以上创建用户库的工作后,你就可以将该库重复使用于任何你希望具有aspectj特性的项目中。
注:在Eclipse中可以通过点击菜单Windows->Preference,然后展开preference窗口左侧的列表到Java->Build Path->User Libraries进行用户库的创建。
该例子中包含四个类:Employee和Department是数据模型类(model class),Main是应用程序的入口,LoggingAspect是“方面”类。
package org.simpleaop.model; public class Employee { private String name; ... //Getters and Setters } package org.simpleaop.model; public class Department { private String location; ... //Getters and Setters }
Main类中展示了Spring中的依赖注入功能。
package org.simpleaop.app; //...import statements public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Employee emp = context.getBean("employee", Employee.class); emp.setName("Jerry Mouse"); Department dept = context.getBean("department", Department.class); dept.setLocation("Disney Land"); System.out.println("Name :"+emp.getName()); System.out.println("Department :"+dept.getLocation()); } }
配置文件spring.xml展示的是依赖注入和AOP的配置细节。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <aop:aspectj-autoproxy /> <bean name="employee" class="org.simpleaop.model.Employee"/> <bean name="department" class="org.simpleaop.model.Department"/> <bean name="loggingAspect" class="org.simpleaop.aspect.LoggingAspect" /> </beans>
LogginAspect类展示了Spring中的AOP实现方法。请注意,它只是一个annotation为@Aspect的简单POJO。 在该类中可以编写任意多的建议(英文为advice,建议是一个AOP术语,指的就是一个带有AOP annotation前缀的函数),可以使用的annotation包括有@Before、@After、@Within、@Around、@Pointcut等。
package org.simpleaop.aspect; //..import statements @Aspect public class LoggingAspect { @Before("execution(public String getName())") public void beforeAdvice(){ System.out.println("Before advice. Runs before the function called"); } //...other advices }
@Before意思就是,名为beforeAdvice的这个建议会在每次对public String getName()这个 函数的调用之前得到执行。@Before还有其它一些变化,比如:
@Before("execution(public String org.simpleaop.Employee.getName())")
不同之处在于,所指定的建议仅会在对Employee类的getName函数调用之前得到执行。
其中还可以使用通配符:
@Before("execution(public * get*())")
表示的是对具有任意返回类型并且没有参数但函数名字的前缀为“get”的public函进行的调用。
@Before("execution(public * get*(..))")
表示的是对具有任意返回类型并且具有零个或多个参数但函数名字的前缀为“get”的public函进行的调用。
@Before("execution(public * get*(*))")
表示的是对具有任意返回类型并且具有一个或多个参数但函数名字的前缀为“get”的public函进行的调用。
需要更多的例子和解释请参见Spring中关于某些方面编程的文档。
有些情况下AOP会非常好用,最常见的用例中可能会有记录日志和性能分析。
AOP象这样的用法多不胜数。这里列举的几项仅仅是蜻蜓点水而已。
评论删除后,数据将无法恢复
评论(1)