这节来学习下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的内在工作机制。《Spring深入解析》PPTX和《SpringStudy》可能包含详细的讲解和示例,可以帮助你更好地理解和应用这些概念。在面试中,对这些原理的清晰...
在IT行业中,构建高效、可扩展的Web应用是至关重要的,而Spring、Spring MVC和Hibernate是Java领域中广泛使用的三大框架,它们各自负责不同的职责,共同构建了一个强大的开发环境。本篇文章将深入探讨如何利用这三大...
收集记录学习spring的点点滴滴,通过每一个小demo,一步步进阶,逐步完善。 实际开发过程很少碰到单模块的项目,所以该项目使用多模块开发,更贴合实际开发要求。 所以检出项目时请检出整个目录,而不是只检出某个...
本文基于编程开发实践,不仅深入解析 Spring 5 的原理与新特性,更从环境准备、顶层结构设计、数据访问等方面一步步地推导出 Spring 的设计原理。 一、Spring 的三个阶段 在学习 Spring 源码之前,我们需要了解 ...
Spring.NET是中国开源社区基于.NET Framework开发的企业级应用框架,它为.NET开发者提供了与Java平台上的Spring...这个DEMO将引导你一步步构建一个完整应用,从配置到编码,再到测试,全方位体验Spring.NET的强大功能。
本教程将详细介绍如何一步步搭建Flex+BlazeDS+Spring的开发环境。 首先,我们需要准备以下软件: 1. **MyEclipse 6.0.1**:这是一个集成开发环境,支持Java和Flex项目的开发。你需要自行下载并安装,确保它是完整...
在Java开发中,Spring框架是一个广泛使用的轻量级框架,它提供了强大的依赖注入(DI)和面向切面编程(AOP)功能,简化了企业级应用的开发。本文将逐步讲解如何在Eclipse环境下搭建Spring框架,以便于理解其工作原理...
这是一份Spring的ppt教程。里面讲诉了spring最新的开发技术。说的都是重点。只要按照课件的来做。一步步的操作。就可以快速学习Spring的开发。跟hibernate的文档相结合,可以让你快速掌握hibernate和Spring的开发。
《构建库存资源管理系统:Spring+jsp+jstl实践指南》 ...总之,学习并实践这个库存资源管理系统,不仅能够提升你的Java Web开发技能,也能让你对Spring框架有更深入的理解,为后续的复杂项目开发打下坚实基础。
Spring Cloud 是一个基于 Java 的...在学习过程中,建议先了解每个组件的基本概念,然后按照例子一步步操作,结合源码分析,加深理解。同时,配合官方文档和其他学习资源,可以更全面地掌握 Spring Cloud 技术栈。
Spring Boot 是一个基于 Java 的框架,它简化了创建和配置基于 Spring 的应用程序的过程。Spring Boot 以其“约定优于配置”的原则著称,旨在提供一种快速、高效地开发生产级应用的方式。Spring Boot 教程是学习这个...
《Spring资料大全》是针对JavaWeb开发者的一份宝贵资源,其中包含了深入学习Spring框架的关键知识点。Spring作为一款广泛应用的开源框架,它简化了Java企业级应用的开发,并提供了丰富的功能,如依赖注入、面向切面...
这个压缩包中的文档很可能会涵盖这些主题,帮助你一步步地了解和实践Spring Cloud的各个方面。学习过程中,理解每个组件的作用和它们之间的协作关系是关键。同时,通过实际操作来加深理解,将理论知识应用到实践中,...
内容概要:帮助读者通过 Spring Boot 框架一步步完成 WebSocket 集成,快速上手WebSocket。在通过两种方式集成的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期...
我们可以按照该文件中的步骤,一步步完成导入过程。 五、编译和构建 Spring 源码 在将 Spring 源码导入 IDEA 后,我们可以使用 Gradle 编译和构建 Spring 源码。在 cmd 中执行 `./gradlew :spring-oxm:...
这本书将带领读者一步步走进Spring的世界,体验其强大而灵活的特性。 在学习Spring的过程中,了解和掌握Java基础知识是前提,因为Spring是建立在Java平台之上的。Java是一种面向对象的语言,具备良好的跨平台性和...
本教程将带你一步步地探索Spring的世界。 1. **Spring框架概述** - Spring的核心理念是依赖注入(Dependency Injection,DI),它通过控制反转(Inversion of Control,IoC)来管理对象的生命周期和相互依赖关系。...
Spring Security 是一个强大...总的来说,这个资源包是学习Spring Security 3的理想资料,无论你是初学者还是有一定经验的开发者,都能从中受益匪浅。通过深入阅读和实践,你将能够构建出安全、健壮的Spring应用程序。
源码阅读是提升开发者技术水平的重要途径,通过深入学习Spring的源码,我们可以更好地理解其工作原理,从而更高效地利用这个框架。 Spring 5是Spring框架的一个重大更新,引入了许多新特性和改进。以下是一些主要的...