这节来学习下AOP,常说的面向切面编程,面向切面编程能提取公用的业务组件做为切面,从而减少实际业务代码的工作量,AOP经常分离的几个切面有:日志管理模块,安全管理模块,事务管理模块。
下面来看下简单的一个日志记录切面(方法前置和后置通知):
先来定义下两个通知:
前置通知:
package aop;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;
/**
* @ClassName: LogBeforeAdvice
* @Description: 日志通知
* @author sunrain
* @date 2011-1-3
*/
public class LogBeforeAdvice implements MethodBeforeAdvice {
private static final Log log = LogFactory.getLog(LogBeforeAdvice.class);
/* (非 Javadoc)
* <p>Title: before</p>
* <p>Description:定义调用方法前的通知 </p>
* @param method
* @param arg1
* @param target
* @throws Throwable
* @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
*/
public void before(Method method, Object[] arg1, Object target)
throws Throwable {
log.info(target.getClass().getName()+"’s "+method.getName()+" invoked");
}
}
后置通知:
package aop;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;;
/**
* @ClassName: LogAfterAdvice
* @Description: 日志通知
* @author sunrain
* @date 2011-1-3
*/
public class LogAfterAdvice implements AfterReturningAdvice {
private static final Log log = LogFactory.getLog(LogAfterAdvice.class);
public void afterReturning(Object arg0, Method method, Object[] arg2,
Object target) throws Throwable {
log.info(target.getClass().getName()+"’s "+method.getName()+" invoked");
}
}
来看看通知是怎么实现通知拦截的:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="helloWorld" class="HelloWorldServiceImpl">
<property name="name">
<value>sunrain</value>
</property>
</bean>
<bean id="personTask" class="ioc.TaskImpl">
<constructor-arg>
<value>sunrain</value>
</constructor-arg>
<property name="living" ref="person"></property>
</bean>
<bean id="dogTask" class="ioc.TaskImpl">
<constructor-arg>
<value>tt</value>
</constructor-arg>
<property name="living" ref="dog"></property>
</bean>
<bean id="person" class="ioc.Person">
</bean>
<bean id="dog" class="ioc.Dog">
</bean>
<bean id="logBeforeAdvice" class="aop.LogBeforeAdvice"></bean>
<bean id="logAfterAdvice" class="aop.LogAfterAdvice"></bean>
<bean id="dogAdviceTask" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>ioc.Task</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>logBeforeAdvice</value>
<value>logAfterAdvice</value>
</list>
</property>
<property name="target">
<ref bean="dogTask"/>
</property>
</bean>
</beans>
这里借助了代理bean ,来代理Task接口,下面写个测试类:
package aop;
import ioc.Task;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class AdviceTest {
/**
* @Title: main
* @Description: AOP 方法前置通知测试类
* @param @param args 设定文件
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
Resource res = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(res);
Task t = (Task)factory.getBean("dogAdviceTask");
t.say();
}
}
对AOP理解的还不够,会慢慢更新的,看下日志:
0103/16:44:17 <INFO > [org.springframework.core.CollectionFactory 66] JDK 1.4+ collections available
0103/16:44:17 <INFO > [org.springframework.core.CollectionFactory 71] Commons Collections 3.x available
0103/16:44:17 <INFO > [org.springframework.beans.factory.xml.XmlBeanDefinitionReader 163] Loading XML bean definitions from file [G:\workspace\SpringStudy\beans.xml]
0103/16:44:18 <INFO > [org.springframework.aop.framework.DefaultAopProxyFactory 64] CGLIB2 available: proxyTargetClass feature enabled
0103/16:44:18 <INFO > [aop.LogBeforeAdvice 30] ioc.TaskImpl’s say invoked
0103/16:44:18 <INFO > [ioc.TaskImpl 32] tt say :汪汪汪
0103/16:44:18 <INFO > [aop.LogAfterAdvice 22] ioc.TaskImpl’s say invoked
下面介绍下用另外一种方式来实现这个:MethodInterceptor
package aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @ClassName: LogAdvice
* @Description: 日志前后置通知模拟
* @author sunrain
* @date 2011-1-3
*/
public class LogAdvice implements MethodInterceptor {
private static final Log log = LogFactory.getLog(LogAdvice.class);
public Object invoke(MethodInvocation invocation) throws Throwable {
log.info(invocation.getThis().getClass().getName()+"’s before "+invocation.getMethod().getName()+" invoked");
invocation.proceed();
log.info(invocation.getThis().getClass().getName()+"’s after "+invocation.getMethod().getName()+" invoked");
return null;
}
}
改下xml配置:
<bean id="logAdvice" class="aop.LogAdvice"></bean>
<bean id="dogAdviceTask1" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>ioc.Task</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>logAdvice</value>
</list>
</property>
<property name="target">
<ref bean="dogTask"/>
</property>
</bean>
在测试类AdviceTest.java中加个调试吧
package aop;
import ioc.Task;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class AdviceTest {
/**
* @Title: main
* @Description: AOP 方法前置通知测试类
* @param @param args 设定文件
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
Resource res = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(res);
Task t = (Task)factory.getBean("dogAdviceTask");
t.say();
t = (Task)factory.getBean("dogAdviceTask1");
t.say();
}
}
看下日志:
0103/17:37:47 <INFO > [org.springframework.core.CollectionFactory 66] JDK 1.4+ collections available
0103/17:37:47 <INFO > [org.springframework.core.CollectionFactory 71] Commons Collections 3.x available
0103/17:37:47 <INFO > [org.springframework.beans.factory.xml.XmlBeanDefinitionReader 163] Loading XML bean definitions from file [G:\workspace\SpringStudy\beans.xml]
0103/17:37:47 <INFO > [org.springframework.aop.framework.DefaultAopProxyFactory 64] CGLIB2 available: proxyTargetClass feature enabled
0103/17:37:47 <INFO > [aop.LogBeforeAdvice 30] ioc.TaskImpl’s say invoked
0103/17:37:47 <INFO > [ioc.TaskImpl 32] tt say :汪汪汪
0103/17:37:47 <INFO > [aop.LogAfterAdvice 22] ioc.TaskImpl’s say invoked
0103/17:37:47 <INFO > [aop.LogAdvice 17] ioc.TaskImpl’s before say invoked
0103/17:37:47 <INFO > [ioc.TaskImpl 32] tt say :汪汪汪
0103/17:37:47 <INFO > [aop.LogAdvice 19] ioc.TaskImpl’s after say invoked
看效果差不多吧,呵呵
这样,我们就能拦截方法的调用了,做一些自己想做的限制或者业务了。比如实现每个用户只能买一个果酱(书上看的喽)
分享到:
相关推荐
Spring核心学习IOC部分:从最简单的BeanFactory开始一步步完善类似Spring的功能
收集记录学习spring的点点滴滴,通过每一个小demo,一步步进阶,逐步完善。 实际开发过程很少碰到单模块的项目,所以该项目使用多模块开发,更贴合实际开发要求。 所以检出项目时请检出整个目录,而不是只检出某个...
主要介绍了JAVA学习之一步步搭建spring框架,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
spring-boot-tutorial:Spring Boot教程带您一步步学习Spring Boot,其中包含大量示例。SpringBoot教程是一本关于Spring Boot学习的开源书。用大量实例带你一步一步走进Spring Boot的世界
这是一份Spring的ppt教程。里面讲诉了spring最新的开发技术。说的都是重点。只要按照课件的来做。一步步的操作。就可以快速学习Spring的开发。跟hibernate的文档相结合,可以让你快速掌握hibernate和Spring的开发。
内容概要:帮助读者通过 Spring Boot 框架一步步完成 WebSocket 集成,快速上手WebSocket。在通过两种方式集成的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期...
第6章:我们从Spring AOP的底层实现技术入手,一步步深入到Spring AOP的内核中,分析它的底层结构和具体实现。 第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、...
内容概要:首先带着读者安装MinIO,并帮助读者通过 Spring Boot 框架一步步完成 MinIO 集成,快速上手分布式对象存储系统。在手写MinIO 工具类的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能...
总共包含10篇代码,从IOC的实现到AOP的实现。自己学习一步步写spring框架。仔细阅读临摹对于准备阅读spring框架源码的人会有很大帮助
学习Spring源码建议构建Spring-framemwork源码环境(这是一个比较麻烦的过程,可能遇到各种问题,需要有耐心..),新建一个模块打断点一步步调试。 举个例子,这是Spring的.class反编译的结果,不但没有注释,暗示性...
第6章:我们从Spring AOP的底层实现技术入手,一步步深入到Spring AOP的内核中,分析它的底层结构和具体实现。 第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、...
这个版本是我在学习spring的时候,根据springlive一书一步步改进得来的。各个章节的代码都保留了。该代码使用的是spring2.5.2,hibernate3。在eclipse3.5.1上使用jdk1.6, tomcat5.5 运行通过。
框架mybatis与spring整合的技术,代码写的很详细,对于小白可以站着教程自己一步步搭建,配合mybatis1一起学习,效果更好
深度解析Spring 5的原理与新特性,从环境准备、顶层结构设计、数据访问等方面一步步推导出Spring设计原理★通过本书你可以:--看源码不再晕车,轻松找到入口。--系统学习设计思想,提高解决问题的效率。--培养架构...
spring+hibernate环境搭配说明文档 java框架spring、hibernate学习的新手们有福音了,这是我亲自搭建的一个环境,从基础到中级升级,一步步教你搭建出可以运行的环境,亲测有效,也教育过好多新手有效!
不建议直接导入,自己新建maven项目,然后一步步的导入文件,这样有利于学习 1分只是象征,如果一分都没有 http://yunpan.cn/QNVzMR8U3gKck 或者SVN:http://code.taobao.org/svn/guestbook/trunk 互相学习,互相...
主要给大家介绍了关于redis与spring整合使用的相关资料,文中通过示例代码将实现的步骤一步步介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
基于ssh框架的新闻发布系统视频教学,可以一步步来学习spring,hibernate,等。
主要介绍了利用Spring Cloud Config结合Bus实现分布式配置中心的相关资料,文中通过示例代码将实现的步骤一步步介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友下面来一起看看吧
亮点三、课程绝大多数代码均是一行一行手工敲入,手把手一步步带领学员从入门到精通. 亮点四、整个课程虽项目不大,但整个项目基本上涉及到JEasyui与后台交互的方方面面,而且讲师框架全部按大的项目架构去搭建...