一、spring(采用配置文件的方式)对AOP实现
1、spring依赖库
* SPRING_HOME/dist/spring.jar
* SPRING_HOME/lib/jakarta-commons/commons-logging.jar
* SPRING_HOME/lib/log4j/log4j-1.2.14.jar
* SPRING_HOME/lib/aspectj/*.jar
2、配置如下
<aop:config>
<aop:aspect id="security" ref="securityHandler">
<aop:pointcut id="allAddMethod" expression="execution(* com.bjsxt.spring.UserManagerImpl.add*(..))"/>
<aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>
</aop:aspect>
</aop:config>
3、spring对AOP的支持
Aspect默认情况下不用实现接口,但对于目标对象(UserManagerImpl.java),在默认情况下必须实现接口(因为sping在底层也是通过java的动态代理来实现)
如果没有实现接口必须引入CGLIB库。会用另一种实现方式,即他在编译时,把你需要在某些方法前需要加的所有检查等全加进去了。
二、源程序示例
package com.bjsxt.spring; public interface UserManager { public void addUser(String username, String password); public void deleteUser(int id); public void modifyUser(int id, String username, String password); public String findUserById(int id); }
package com.bjsxt.spring; public class UserManagerImpl implements UserManager { public void addUser(String username, String password) { System.out.println("-------UserManagerImpl.addUser()----------"); } public void deleteUser(int id) { System.out.println("-------UserManagerImpl.deleteUser()----------"); } public String findUserById(int id) { System.out.println("-------UserManagerImpl.findUserById()----------"); return null; } public void modifyUser(int id, String username, String password) { System.out.println("-------UserManagerImpl.modifyUser()----------"); } }
package com.bjsxt.spring; public class SecurityHandler { private void checkSecurity() { System.out.println("----------checkSecurity()---------------"); } }
package com.bjsxt.spring; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Client { public static void main(String[] args) { BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); UserManager userManager = (UserManager)factory.getBean("userManager"); userManager.addUser("张三", "123"); userManager.deleteUser(1); } }
<?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:tx="http://www.springframework.org/schema/tx" 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/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="securityHandler" class="com.bjsxt.spring.SecurityHandler"/> <bean id="userManager" class="com.bjsxt.spring.UserManagerImpl"/> <aop:config> <aop:aspect id="security" ref="securityHandler"><!--此处声明了切面类--> <aop:pointcut id="allAddMethod" expression="execution(* com.bjsxt.spring.UserManagerImpl.add*(..))"/> <!--上面这一句声明了在哪些方法使用时拦截,称作pointcut--> <aop:before method="checkSecurity" pointcut-ref="allAddMethod"/> <!--上面这一句声明了在那些方法使用前拦截,还是方法使用后拦截,称作before Advice或者叫after Advice--> </aop:aspect> </aop:config> </beans>
三、在以上示例程序中通过Advice中添加一个JoinPoint参数
可参考附件程序(spring_aop3.rar )
我们可以通过Advice中添加一个JoinPoint参数,这个值会由spring自动传入,从JoinPoint中可以取得
参数值、方法名等等
package com.bjsxt.spring;
import org.aspectj.lang.JoinPoint;
public class SecurityHandler {
private void checkSecurity(JoinPoint joinPoint) {
System.out.println("----------checkSecurity()---------------");
}
}
备注:因为例三中的UserManagerImpl 没有通过一个接口UserManager去实现,所以不能轻而易举地产生动态代理了,不过还好在spring中有一个叫cglib的jar包(* SPRING_HOME/lib/cglib/*.jar),引用这个jar包后,并在切面类
加入一个参数(joinPoint)即可达到和例二一样的效果了!