Spring review--动态代理和AOP代码的演化

来源:互联网 发布:双面羊绒缝合机 淘宝 编辑:程序博客网 时间:2024/06/05 08:15


客户端代码,首先通过容器实例化applicationContext.xml里面的Bean,然后调用add方法。

<span style="font-size:14px;"><span style="font-size:14px;">public class Client {public static void main(String[] args) {BeanFactory factory =new ClassPathXmlApplicationContext("classpath:applicationContext.xml");UserManager userManager =(UserManager)factory.getBean("userManager");  userManager.addUser("wm", "123");}}</span></span>



SecurityHandler, 采用动态代理的时候,把具体的执行委托给了代理类进行执行。采用AOP了之后,设置切入点,触发切入条件后,执行扩展操作,然后回调,继续执行之前的业务逻辑。

<span style="font-size:14px;"><span style="font-size:14px;">@Aspectpublic class SecurityHandler  {//将横切性关注点 模块化,删除动态代理,定义Aspect/*private Object targetObject;public Object  createProxyInstance(Object targetObject){this.targetObject=targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),    targetObject.getClass().getInterfaces(),   this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {checkSecurity();//调用目标方法Object ret = method.invoke(targetObject , args);return ret;}*///定义PointCut,PointCut的名称为addMethod(),此方法没有返回值和参数。该方法就是标识,不进行调用。@Pointcut("execution(* add*(..))")private void addMethod(){};/** * 定义Advice,表示我们的Advice应用到哪些pointcut订阅的JoinPoint上  */@Before("addMethod()")public void checkSecurity(){System.out.println("------checkSecurity()-------");}}</span></span>


UserManager,执行真正业务逻辑,需要实现的接口。

<span style="font-size:14px;"><span style="font-size:14px;">public interface UserManager {public void addUser(String name,String password);public void delUser(int userId);public String findUserById(int userId);public void modifyUser(int userId,String userName,String password);}</span></span>


UserManagerImpl,执行执行真正业务逻辑的具体实现。

<span style="font-size:14px;"><span style="font-size:14px;">public class UserManagerImpl implements UserManager {@Overridepublic void addUser(String name, String password) {System.out.println("---UserManagerImpl.addUser()-----------");}@Overridepublic void delUser(int userId) {System.out.println("---UserManagerImpl.delUser()-----------");}@Overridepublic String findUserById(int userId) {System.out.println("---UserManagerImpl.findUserById()-----------");return "wm";}@Overridepublic void modifyUser(int userId, String userName, String password) {System.out.println("---UserManagerImpl.modifyUser()-----------");}}</span></span>



applicationContext.xml 对AOP和容器进行配置。

<span style="font-size:14px;"><span style="font-size:14px;"><?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"           default-autowire="byName"><aop:aspectj-autoproxy/><bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/> <bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/></beans> </span></span>


UserManagerImplProxy,开始使用的代理类,代理类跟被代理者都通过实现UserManager接口。添加Aop之后,代理类就不起作用了,就注释掉了。

<span style="font-size:14px;"><span style="font-size:14px;">/*package com.bjpowernode.spring;public class UserManagerImplProxy implements UserManager {private UserManager UserManager;public UserManagerImplProxy(UserManager userManager) {this.UserManager = userManager;}@Overridepublic void addUser(String name, String password) {// TODO Auto-generated method stub}@Overridepublic void delUser(int userId) {// TODO Auto-generated method stub}@Overridepublic String findUserById(int userId) {// TODO Auto-generated method stubreturn null;}@Overridepublic void modifyUser(int userId, String userName, String password) {// TODO Auto-generated method stub}}*/</span></span>


Spring配置AOP有多种形式,上面的配置方式是annotation方式,还可以采用xml配置方式。


SecurityHandler可以简化成如下代码:

<span style="font-size:14px;">public class SecurityHandler  {public void addAddMethod(){}public void checkSecurity(){System.out.println("------checkSecurity()-------");}}</span>


applicationContext.xml如下:

<span style="font-size:14px;"><?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"           default-autowire="byName"><bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/> <bean id="securityHandler" class="com.bjpowernode.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></beans> </span>


Aop运行结果:



xml里面对表达式的配置多样,常用的如下。某些包下面的类和某些包下面删除和添加操作的类的Aop的配置:

<span style="font-size:14px;">execution(* com.bjpowernode.spring.*.* (..))</span>
<span style="font-size:14px;">execution(* com.bjpowernode.spring.*.add*(..)|| </span><span style="font-size: 14px; font-family: Arial, Helvetica, sans-serif;">com.bjpowernode.spring.*.del*(..))</span>



0 0
原创粉丝点击