一、静态代理
参见代码
二、动态代理
参见j2se专题动态代理与反射
三、AoP介绍
根据上例中spring_dynamic_proxy程序
四、使用Annotation的实现举例
1、程序
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; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; /** * 定义Aspect * @author Administrator * */ @Aspect public class SecurityHandler { /** * 定义Pointcut,Pointcut的名称就是allAddMethod,此方法不能有返回值和参数,该方法只是一个 * 标识,如在下面Advice就用到了 * * Pointcut的内容是一个表达式,描述那些对象的那些方法(订阅Joinpoint) */ @Pointcut("execution(* add*(..)) || execution(* del*(..))") private void allAddMethod(){}; /** * 定义Advice,标识在那个切入点何处织入此方法 */ @Before("allAddMethod()") 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); } }
2、spring配置文件
<?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">
<aop:aspectj-autoproxy/>
<bean id="securityHandler" class="com.bjsxt.spring.SecurityHandler"/>
<bean id="userManager" class="com.bjsxt.spring.UserManagerImpl"/>
</beans>
3、说明
spring对AOP的只是(采用Annotation的方式)
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)、配置时需要增加对Annotation的支持
Windows/myeclispe/Fileter and Editor/xml/xml catelog/选中url,然后点击add,浏览选中Spring/dist/resource/spring_aop_2.0.xsd/然后再将刚才选择url的位置,选中Schema Location
最后在最后一行已有的路径上加上/spring_aop_2.0.xsd(即和第一行最后保持一致ok)
3)、采用Aspect定义切面在Aspect定义Pointcut和Advice、启用AspectJ对Annotation的支持并且将Aspect类和目标对象配置到Ioc容器中
注意:在这种方法定义中,切入点的方法是不被执行的,它存在的目的仅仅是为了重用切入点
即Advice中通过方法名引用这个切人点
关于针对哪些方法表达式等书写可以参考Spring开发参考手册(见附件)的第6.2.3.4示例。