- 浏览: 205804 次
- 性别:
- 来自: 紫禁城
文章分类
最新评论
-
a1439226817:
<!doctype html><html l ...
发布一个支持N级下拉列表联动的控件 -
a1439226817:
也不高个测试的demo,别人怎么用啊
发布一个支持N级下拉列表联动的控件 -
davaidgao:
不全啊,这是
Spring3.x权威开发指南 -
caizi12:
对于map绑定很是不方便,现在的做法,需要创建一User类,再 ...
浅谈 SpringMVC 数据绑定 -
joeyhuang:
不全啊..
Spring3.x权威开发指南
一。创建切面:
Spring中的通知类型有四种:
Around:拦截对目标对象方法调用,
Before:在目标方法被调用之前调用,
After:在目标方法被调用之后调用,
Throws:当目标方法抛出异常时调用。
1)下面是一个Before类型的简单例子。
1.首先创建一个拦截的类:
package cn.itcast;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {//实现MethodBeforeAdvice接口
Log log = LogFactory.getLog(this.getClass());
public MyMethodBeforeAdvice() {
super();
}
public void before(Method arg0, Object[] arg1, Object arg2)//实现MethodBeforeAdvice接口的before方法,
throws Throwable {
StringBuilder sb = new StringBuilder();
if (arg1 == null) {
sb = new StringBuilder("无参数!");
} else {
for (int i = 0; i < arg1.length; i++) {
if (i != arg1.length - 1) {
sb.append(arg1[i] + ",");
} else {
sb.append(arg1[i]);
}
}
}
log.info("类名: " + arg2.getClass().getName() + " 方法名: "
+ arg0.getName() + " 参数:" + sb.toString());
}
}
这个类中我们没做太多的事,就是把方法名等信息打印出来而已,当然你可以根据业务需求做其他的很多事情。
2.
写一个配置文件:applicationContext.xml
<?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="myArrayList" class="java.util.ArrayList" />
<bean id="myMethodBeforeAdvice" class="cn.itcast.MyMethodBeforeAdvice" />
<bean id="collection" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<!--指定拦截类的名字,可以加入多个,它会去检查此类实现的是什么接口,然后去调用里面相应的方法-->
<list>
<value>myMethodBeforeAdvice</value>
</list>
</property>
<property name="target"><!--指定目标对象-->
<ref bean="myArrayList" />
</property>
<property name="proxyInterfaces">
<!--指定目标对象实现的接口,也可以是多个-->
<list>
<value>java.util.Collection</value>
</list>
</property>
</bean>
</beans>
3.再写一个测试类
package cn.itcast.test;
import java.util.Collection;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMySpringAop extends TestCase {
ApplicationContext applicationContext = null;
Collection collection = null;
protected void setUp() throws Exception {
super.setUp();
applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
}
public void testMySpring() {
collection = (Collection) applicationContext.getBean("collection");
collection.add("zhangsan");
assertEquals(1, collection.size());
}
}
运行!结果为:
类名: java.util.ArrayList 方法名: add 参数:zhangsan
类名: java.util.ArrayList 方法名: size 参数:无参数!
看....简单吧?!
2) 再来一个After的例子。
1.首先创建一个拦截的类:
package cn.itcast;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
public class MyAfterReturningAdvice implements AfterReturningAdvice {
Log log = LogFactory.getLog(this.getClass());
public MyAfterReturningAdvice() {
super();
}
public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
StringBuilder sb = new StringBuilder();
if (arg2 == null) {
sb = new StringBuilder("无参数!");
} else {
for (int i = 0; i < arg2.length; i++) {
if (i != arg2.length - 1) {
sb.append(arg2[i] + ",");
} else {
sb.append(arg2[i]);
}
}
}
log.info("返回值: " + arg0.toString() + " 类名: "
+ arg3.getClass().getName() + " 方法名: " + arg1.getName()
+ " 参数:" + sb.toString());
}
}
2.把上面的XMl文件稍加改动即可,意思和上面的差不多,这里就不多加注释了。
<?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="myArrayList" class="java.util.ArrayList" />
<bean id="myAfterReturningAdvice" class="cn.itcast.MyAfterReturningAdvice" />
<bean id="collection" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<value>myAfterReturningAdvice</value>
</property>
<property name="target">
<ref bean="myArrayList" />
</property>
<property name="proxyInterfaces">
<value>java.util.Collection</value>
</property>
</bean>
</beans>
3.测试类依然用上面那个。
运行!结果为:
返回值的类型: true 类名: java.util.ArrayList 方法名: add 参数:zhangsan
返回值的类型: 1 类名: java.util.ArrayList 方法名: size 参数:无参数!
看......现在返回值也取出来了.........
3) 再来看一个Around的例子。步骤和上面一样,
1.首先也是创建一个拦截的类:
package cn.itcast;
import java.lang.reflect.Method;
import java.util.ArrayList;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyMethodInterceptor implements MethodInterceptor {
public MyMethodInterceptor() {
super();
}
Log log = LogFactory.getLog(this.getClass());
public Object invoke(MethodInvocation arg0) throws Throwable {
Object[] arguments = arg0.getArguments();
Method method = arg0.getMethod();
Object objName = arg0.getThis();
StringBuilder sb = new StringBuilder();
if (arguments == null) {
sb = new StringBuilder("无参数!");
} else {
for (int i = 0; i < arguments.length; i++) {
if (i != arguments.length - 1) {
sb.append(arguments[i] + ",");
} else {
sb.append(arguments[i]);
}
}
}
//在调用目标方法之前做的事
log.info("类名: " + objName.getClass().getName() + " 方法名: " + method.getName()
+ " 参数:" + sb.toString());
Object object = arg0.proceed();//通过调用此方法来调用目标方法。
//在调用目标方法之后做的事
if(objName instanceof ArrayList){
ArrayList arrayList = (ArrayList) objName;
arrayList.add("lisi");
arrayList.add("wangwu");
log.info("size = " + arrayList.size());
}
return object;
}
}
2.把上面的XMl文件稍加改动即可,意思和上面的差不多,这里就不多加注释了。
<?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="myArrayList" class="java.util.ArrayList" />
<bean id="myMethodInterceptor" class="cn.itcast.MyMethodInterceptor" />
<bean id="collection" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<value>myMethodInterceptor</value>
</property>
<property name="target">
<ref bean="myArrayList" />
</property>
<property name="proxyInterfaces">
<value>java.util.Collection</value>
</property>
</bean>
</beans>
3.运行!结果:
类名: java.util.ArrayList 方法名: add 参数:zhangsan
size = 3
类名: java.util.ArrayList 方法名: size 参数:无参数!
size = 5
我们类分析一下运行的结果。在测试类中调用了一次目标类的add方法,此时size为1,然后在拦截类里面把对象取出来调用了两次add方法,这时size为3,也就是我们看到的第一个size,接着在测试类中调用了一次size方法,此时它又被拦截了,所以再一次调用了两个add方法,最后的size当然就是5了。当然如果我们这里用的是Set集合就不会再add后面的两个已存在的对象了。
4)一个ThrowsAdvice的例子。步骤和上面一样,
1.写一个拦截异常的类。这里面可以有多个带不同异常参数类型afterThrowing方法,运行时根据抛出异常的类型去调用恰当的方法,
package cn.itcast;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class MyThrowsAdvice implements ThrowsAdvice {
public MyThrowsAdvice() {
super();
// TODO Auto-generated constructor stub
}
public void afterThrowing(Method method, Object[] args, Object target,
NullPointerException npe) {
System.out.println("调用 " + target.getClass().getName() + " 的 "
+ method.getName() + " 方法时发生了 " + npe.getClass().getName()
+ " 异常!");
}
}
2.xml文件。把上面的稍加修改:
<?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="myArrayList" class="java.util.ArrayList" />
<bean id="myMethodBeforeAdvice" class="cn.itcast.MyMethodBeforeAdvice" />
<bean id="myAfterReturningAdvice" class="cn.itcast.MyAfterReturningAdvice" />
<bean id="myMethodInterceptor" class="cn.itcast.MyMethodInterceptor" />
<bean id="myThrowsAdvice" class="cn.itcast.MyThrowsAdvice" />
<bean id="collection" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<value>myThrowsAdvice</value>
</property>
<property name="target">
<ref bean="myArrayList" />
</property>
<property name="proxyInterfaces">
<value>java.util.Collection</value>
</property>
</bean>
</beans>
3.写一个main方法来测试一下:
package cn.itcast;
import java.util.Collection;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {
public MainClass() {
super();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext applicationContext = null;
Collection collection = null;
applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
collection = (Collection) applicationContext.getBean("collection");
collection.add("zhangsan");
Object[] object = null;
collection.toArray(object);//故意来抛出一个异常试试看
}
}
来看看运行结果:
调用 java.util.ArrayList 的 toArray 方法时发生了 java.lang.NullPointerException 异常!
Exception in thread "main" java.lang.NullPointerException
at java.util.ArrayList.toArray(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy0.toArray(Unknown Source)
at cn.itcast.MainClass.main(MainClass.java:29)
看到了吗?我们在拦截异常类里面的打印语句出来了:
调用 java.util.ArrayList 的 toArray 方法时发生了 java.lang.NullPointerException 异常!
当然在这里你还可以做很多事情。在本程序里面仅打印出这条简单的信息而已。
下面的是系统抛出的。由此可以看出,如果有异常的话,代理对象捕获异常并且调用合适的ThrowsAdvice方法。ThrowsAdvice被执行后,原来的异常继续被抛出,并且象其他异常一样被传播出去。
发表评论
-
浅谈 SpringMVC 数据绑定
2011-03-24 13:41 4651查看spring源码可以看出spring支持转换的数据类型: ... -
使用 Spring 2.5 基于注解驱动的 Spring MVC
2010-08-23 16:39 836基于注解的配置有越来越流行的趋势,Spring 2 ... -
Spring3.x权威开发指南
2010-08-23 11:30 3115Spring3.x权威开发指南 -
几个Spring的小例子
2006-09-10 17:27 812一 .第一个Spring程序: 首先创建一个接口:packag ... -
对Bean和Bean工厂进行后处理
2006-09-19 09:23 7971.对Bean进行后处理,必须实现BeanPostProces ... -
使用数据库连接池和jdbc中调用存储过程
2006-09-22 15:21 1025数据库连接池:数据库连接不仅仅是在应用服务器与数据库之间建立一 ... -
一个使用JdbcTemplate增加一组数据的完整例子
2006-09-23 12:44 1552一个使用JdbcTemplate增加 ... -
Hibernate学习笔记
2006-10-12 20:43 647J2EE体系结构分为三层:1.表示层(JSP/Servlet) ... -
一个使用ibatis对数据库增删改查的例子
2006-10-28 22:29 1326一个使用ibatis对数据库增删改查的例子:这里用的开发环境是 ... -
ibatis和Spring整合的详细例子
2006-10-28 22:30 1020ibatis和Spring整合的详细例子,数据库用的是mysq ... -
Spring XML配置十二个最佳实践
2006-11-01 13:28 644Spring XML配置十二个最佳 ... -
Servlet的生命周期
2006-11-10 00:27 1153Servlet的生命周期 当 ... -
JSP Struts之HTML标签库详解
2006-11-28 21:50 859JSP Struts之HTML标签库详解 Struts提供 ... -
WebWork 入门示例
2006-12-07 00:12 719准备工作: Eclipse3.2 MyEclip ...
相关推荐
下面我们将详细探讨如何在Spring中创建和使用自定义切面,以及AspectJ的相关知识。 首先,让我们理解什么是切面。在AOP中,切面是跨越多个对象的行为或关注点的模块化,例如日志记录、事务管理、性能监控等。自定义...
在IT行业中,Spring框架是Java企业级应用开发的首选,其强大的功能之一就是AOP(面向切面编程)。本文将详细解析Spring AOP的三种实现方式,帮助你深入理解这一重要概念。 首先,理解AOP的基本概念至关重要。AOP是...
- 为了确保自定义切面中的事务能够正常工作,我们需要注意事务管理器切面与其他自定义切面之间的`order`属性设置。 - 对于一般的业务逻辑来说,将事务管理器的`order`值设置得稍微高一点(例如200),而自定义切...
通过利用Spring的AOP(面向切面编程)特性,特别是@AspectJ注解的支持,我们可以创建灵活、可重用的业务逻辑切面,从而在不修改现有代码的情况下,对应用程序的行为进行增强。 ### Spring自定义切面的核心概念 ###...
3. **配置XML**: 在Spring的配置文件(如`applicationContext.xml`)中,你需要启用AOP代理并声明切面。首先,启用AOP上下文: ```xml ``` 然后,声明切面,指定其类和通知: ```xml (* ...
在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点从核心业务逻辑中分离出来,例如日志记录、事务管理、性能监控等。本示例将深入探讨如何在Spring中实现AOP,特别是通过注解的方式。...
面向切面编程(AOP,Aspect Oriented Programming)是Spring框架中的一个重要特性,它提供了一种模块化和声明式的方式来处理程序中的横切关注点,如日志、事务管理、安全控制等。AOP的核心概念包括切面、通知、连接...
创建切面** 创建`Audience`类作为切面类,即观众类。通过`@Aspect`注解将其定义为切面,并使用`@Around`注解指定`watchPerformance()`方法作为`perform()`切点的环绕通知。 ```java @Aspect public class ...
Spring框架的AOP(面向切面编程)是其核心特性之一,它允许开发者在不修改原有代码的情况下,通过切面来插入额外的功能,比如日志记录、事务管理、性能监控等。在Spring AOP中,主要涉及到两个重要的库:...
在Spring中,AOP通过代理机制实现了切面编程,允许我们在不修改原有业务代码的情况下,插入额外的功能。 一、理解AOP概念 1. 切面(Aspect):AOP的核心概念,代表一个关注点的模块化,这个关注点可能会横切多个...
在Spring Boot应用中,面向切面编程(AOP)是一种强大的设计模式,它允许我们以声明式的方式插入代码,比如日志记录、事务管理或权限检查。Aspect是AOP的核心概念,它封装了关注点,使得我们可以将这些关注点与业务...
Spring AOP,全称Spring面向切面编程,是Spring框架中的一个重要组成部分,它提供了一种在不修改原有代码的情况下,对程序进行功能增强的技术。面向切面编程(Aspect Oriented Programming,AOP)的核心思想是将关注...
在Spring框架中,面向切面编程(AOP)是一种强大的设计模式,它允许开发者将关注点分离,将横切关注点(如日志、事务管理、权限检查等)与核心业务逻辑解耦。本篇文章将深入探讨如何使用Spring的动态代理机制实现AOP...
Spring框架是Java领域中实现AOP的常用工具,它通过提供声明式的方式来实现切面编程,使开发者能够更专注于业务逻辑。 在Spring框架中,AOP主要通过以下几个核心概念来实现: 1. **切面(Aspect)**:切面是关注点...
6. **代理(Proxy)**:Spring AOP通过创建代理对象来实现切面功能。有JDK动态代理和CGLIB代理两种方式。如果目标类实现了接口,Spring会使用JDK动态代理;如果没有,Spring会使用CGLIB生成一个子类来作为代理。 在...
在IT行业中,Spring MVC、MyBatis Plus以及AOP(面向切面编程)是Java Web开发中的重要组件,常用于构建高效、灵活的企业级应用。本项目“Spring MVC Mybatis Plus 实现AOP 切面日志系统”旨在提供一个基础的日志...
在Spring框架中,AOP(Aspect Oriented Programming,面向切面编程)是一种强大的设计模式,它允许程序员将关注点从核心业务逻辑中分离出来,如日志、事务管理等。在"day39-Spring 06-Spring的AOP:带有切点的切面...
Struts2、Spring和Hibernate是Java Web开发中的三大框架,它们各自负责不同的职责:Struts2主要用于MVC(模型-视图-控制器)架构的实现,Spring提供了强大的依赖注入和面向切面编程功能,而Hibernate则是一个优秀的...
在IT领域,Spring框架是Java开发中的核心组件之一,它为开发者提供了许多强大的功能,包括依赖注入、面向切面编程(AOP)以及事务管理。本章将详细探讨Spring4中的切面事务处理、事物通知以及传播行为。 一、切面...
Spring AOP是Spring框架的一个重要特性,它实现了面向切面编程,允许开发者定义“切面”,即关注点的模块化,比如日志记录、性能监控、安全控制等。切面通过通知(advises)来增强其他对象的行为。Spring支持多种...