`
gaosililn
  • 浏览: 73387 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

SSH学习:Spring AOP系列学习

 
阅读更多

Spring系列学习之Spring AOP
1.何谓AOP?
    aop是开发中面向切面编程的一种思想
    AOP与OOP的对比:OOP是面向对象编程的一种思想。即模拟现实世界模式一切皆对象;AOP是面前切面,即将过程横切处理的思想。
2.AOP的作用:
    1.提供了声明式的服务
    2.允许用户定义自己的切面
3.AOP常见的实现:
    1.Proxy方式实现AOP方式:
    2.CGLib方法实现AOP
    3.Spring AOP实现:注解aspect方式实现;基于配置文件方式实现
4.Spring AOP的实现:
    1.纯Java实现,无需特殊编译过程,不需要控制类加载层次;
    2.只支持方法执行连接点
    3.不是为了提供最完整的AOP实现,而是侧重提供一种AOP实现与Spring IOC容器之间的整合,用于帮助企业级应用提供常见问题的解决途径。
    4.Spring AOP默认使用标准的JavaSE动态代理作为AOP的代理器,使得所用的接口都可以被代理
    5.Spring AOP代理也可以使用CGLib代理

5.Spring AOP实现之基于注解aspect方式实现:
    1.代理对象业务代码:

package aop.aspect;

		public class Student {

			public String print(String name) {
				System.out.println(name + "print");
				return "hello word";
			}
			

		}

     2.注解实现的切面代码

package aop.aspect;

		import org.aspectj.lang.ProceedingJoinPoint;
		import org.aspectj.lang.annotation.After;
		import org.aspectj.lang.annotation.AfterReturning;
		import org.aspectj.lang.annotation.Around;
		import org.aspectj.lang.annotation.Aspect;
		import org.aspectj.lang.annotation.Before;
		import org.aspectj.lang.annotation.Pointcut;

		@Aspect
		public class StudnetInterceptor {

			/**
			 * 打印方法AOP
			 */
			@Pointcut("execution(* aspect.Student.print(..))")
			// @Pointcut("execution(*
			// com.jike.spring.chapter09.aop.aspect.Student.*(..))")
			public void printMethod() {
			}

			@Before("printMethod()")
			public void printBeforeAdvice() {
				System.out.println("printBeforeAdvice()!");
			}

			@AfterReturning(pointcut = "printMethod()", returning = "flag")
			public void printAfterAdvice(String flag) {
				System.out.println("printAfterAdvice()! " + flag);
			}

			@After("printMethod()")
			public void finallyAdvice() {
				System.out.println("finallyAdvice()!");
			}

			@Around("printMethod() && args(name)")
			public Object printAroundAdvice(ProceedingJoinPoint pjp, String name) throws Throwable {
				Object result = null;
				if (name.equals("whc"))
					pjp.proceed();
				else
					System.out.println("print()方法以及被拦截...");
				return result;
			}

		}

     3.测试代码:

public class Test {

			public static void main(String[] args) {
				ApplicationContext ctx = new ClassPathXmlApplicationContext("config/conf-aspect.xml");
				Student stu = (Student) ctx.getBean("stu");
				stu.print("whc");
			}

		}

 6.Spring AOP实现之aspect配置文件方式实现:

    1.被代理对象的业务事务代码

package aop.xml;

		public class Student {

			public String print(String name) {
				System.out.println(name + "print");
				return "hello word";
			}

		}

     2.基于配置文件实现的切面代码

package aop.xml;

		import org.aspectj.lang.ProceedingJoinPoint;
		import org.aspectj.lang.annotation.After;
		import org.aspectj.lang.annotation.AfterReturning;
		import org.aspectj.lang.annotation.Around;
		import org.aspectj.lang.annotation.Aspect;
		import org.aspectj.lang.annotation.Before;
		import org.aspectj.lang.annotation.Pointcut;

		/**
		 * Xml方式实现AOP切面
		 * 
		 * @author lilin
		 * @time 2016年5月27日 下午11:46:46
		 * @email gaosi0812@gmail.com
		 * @blog http://gaosililin.iteye.com
		 * @school USC
		 * @team Geowind
		 */
		public class StudnetInterceptor {
			/**
			 * 打印方法AOP
			 */

			public void printMethod() {
			}

			public void printBeforeAdvice() {
				System.out.println("printBeforeAdvice()!");
			}

			public void printAfterAdvice(String name) {
				System.out.println("printAfterAdvice()! " + name);
			}

			public void finallyAdvice() {
				System.out.println("finallyAdvice()!");
			}

			public Object printAroundAdvice(ProceedingJoinPoint pjp, String name) throws Throwable {
				Object result = null;
				if (name.equals("whc"))
					pjp.proceed();
				else
					System.out.println("print()方法以及被拦截...");
				return result;
			}
		}

    3.测试代码:

package aop.xml;
			
		import org.springframework.context.ApplicationContext;
		import org.springframework.context.support.ClassPathXmlApplicationContext;

		public class Test {

			public static void main(String[] args) {
				ApplicationContext ctx = new ClassPathXmlApplicationContext("config/conf-xml.xml");
				Student stu = (Student) ctx.getBean("stu");
				stu.print("whc1");
			}

		}

     4.配置文件:

		<?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"
			xsi:schemaLocation="http://www.springframework.org/schema/beans 
			http://www.springframework.org/schema/beans/spring-beans.xsd  
			http://www.springframework.org/schema/aop 
			http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
			<aop:aspectj-autoproxy />
			<bean id="stu" class="xml.Student"></bean>
			<bean id="interceptor" class="xml.StudnetInterceptor"></bean>

			<aop:config>
				<aop:aspect id="stuInterceptor" ref="interceptor">
					<aop:before pointcut="execution(* xml.Student.print(..))"
						method="printBeforeAdvice" />
					<aop:after-returning pointcut="execution(* xml.Student.print(..))"
						method="printAfterAdvice" />
					<aop:after pointcut="execution(* xml.Student.print(..))"
						method="finallyAdvice" />
					<aop:around pointcut="execution(* .xml.Student.print(..)) and args(name)"
						method="printAroundAdvice" />
				</aop:aspect>
			</aop:config>
		</beans>  

 7.Spring pointCut:



8.aop通知的执行的顺序:
    1.before:方法执行前
    2.around:环绕,方法执行之前,但是该方法第一个参数必须是ProceedingJoinPoint
    3.after-throwing:方法抛出异常之后
    4.after:方法执行之后
    5.after-returning:方法返回值之后

   示例代码:

     1.目标接口代码

package aop.aop;

public interface Foo {
	void play(String name);
}

    2.目标接口实现类代码

package aop.aop;

public class FooImpl implements Foo {

	@Override
	public void play(String name) {
		System.out.println("paling with " + name);
		throw new RuntimeException();
	}

}

   3.Interceptor类代码

package aop.aop;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * Xml配置实现通知
 * 
 * @author lilin
 * @time 2016年5月31日 下午12:36:52
 * @email gaosi0812@gmail.com
 * @blog http://gaosililin.iteye.com
 * @school USC
 * @team Geowind
 */
public class FooInterceptor {
	/**
	 * 前置通知
	 */
	public void beforePaly() {
		System.out.println("FooInterceptor.beforePlay");
	}

	/**
	 * 后置通知
	 */
	public void afterPlay() {
		System.out.println("FooInterceptor.afterPlay");
	}

	/**
	 * 返回返回值后通知
	 */
	public void afterReturnning() {
		System.out.println("FooInterceptor.afterReturnning");
	}

	/**
	 * 抛出异常后通知
	 */
	public void throwExcetion() {
		System.out.println("FooInterceptor.throwExcetion");
	}

	/**
	 * 环绕通知 。第一个参数必须是ProceedingJoinPoint
	 * 
	 * @param pjp
	 * @param name
	 * @return
	 * @throws Throwable
	 */
	public Object printAroundAdvice(ProceedingJoinPoint pjp, String name) throws Throwable {
		Object result = null;
		if (name.equals("jing")) {
			try {
				result = pjp.proceed();
			} catch (Exception e) {
				System.out.println("诶呀,异常了");
			}
		} else {
			System.out.println("print()方法以及被拦截...");
		}
		return result;
	}

}

    4.测试类代码

package aop.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AopTest {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("config/introduce-introduce.xml");
		Foo foo = (Foo) context.getBean("foo");
			foo.play("jing");

	}

}

   5.配置文件

<?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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd  
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
	<aop:aspectj-autoproxy />
	<bean id="foo" class="aop.aop.FooImpl"></bean>
	<bean id="foointerceptor" class="aop.aop.FooInterceptor"></bean>
	<aop:config>
		<aop:aspect id="fooInterceptor" ref="foointerceptor">
			<aop:before method="beforePaly" pointcut="execution(* aop.aop.Foo.play(..) )" />
			<aop:after-returning method="afterReturnning"
				pointcut="execution(* aop.aop.Foo.play(..))" />
			<aop:after method="afterPlay" pointcut="execution(* aop.aop.Foo.play(..))" />
			<aop:around pointcut="execution(*  aop.aop.Foo.play(..)) and args(name)"
				method="printAroundAdvice" />
			<aop:after-throwing method="throwExcetion"
				pointcut="execution(* aop.aop.Foo.play(..))" />
		</aop:aspect>
	</aop:config>


</beans>  

   6.结果排序



 9.Advice  AOP增强

    Aop Advice中除了Introdutions引介增强外,其他的都是方法级别的增强,Introdutions引介增强是类级别的增强

  实现代码示例:

  1.增强对象的接口

package advice.advice;

/**
 * 增强对象的接口
 * 
 * @author lilin
 * @time 2016年5月31日 上午11:22:19
 * @email gaosi0812@gmail.com
 * @blog http://gaosililin.iteye.com
 * @school USC
 * @team Geowind
 */
public interface Foo {

	void play(String name);

}

 

    2.增强的实现类

package advice.advice;

/**
 * 增强对象的实现类
 * 
 * @author lilin
 * @time 2016年5月31日 上午11:22:45
 * @email gaosi0812@gmail.com
 * @blog http://gaosililin.iteye.com
 * @school USC
 * @team Geowind
 */
public class FooImpl implements Foo {

	@Override
	public void play(String name) {
		System.out.println("paling with " + name);
		// throw new RuntimeException();
	}

}

     3.前置增强

package advice.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

/**
 * 前置增强
 * 
 * @author lilin
 * @time 2016年5月31日 上午11:27:42
 * @email gaosi0812@gmail.com
 * @blog http://gaosililin.iteye.com
 * @school USC
 * @team Geowind
 */
public class BeforeAdvice implements MethodBeforeAdvice {

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("BeforeAdvice.before:method " + method.getName() + " aug:" + args[0]);
	}

}

    5.后置增强

package advice.advice;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

/**
 * 后置增强
 * 
 * @author lilin
 * @time 2016年5月31日 上午11:23:42
 * @email gaosi0812@gmail.com
 * @blog http://gaosililin.iteye.com
 * @school USC
 * @team Geowind
 */
public class AfterAdvice implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
		System.out.println("AfterAdvice.afterReturning.  method:" + method.getName() + " arg:" + args[0]);
	}

}

    6.环绕增强

package advice.advice;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 环绕增强
 * 
 * @author lilin
 * @time 2016年5月31日 上午11:28:23
 * @email gaosi0812@gmail.com
 * @blog http://gaosililin.iteye.com
 * @school USC
 * @team Geowind
 */
public class AroundAdvice implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		Method method = arg0.getMethod();
		Object[] arguments = arg0.getArguments();
		// 环绕增强 前
		System.out.println("AroundAdvice.invoke.before  method:" + method.getName());
		// 放射方式调用目标方法
		Object proceed = arg0.proceed();
		// 环绕增强 后
		System.out.println("AroundAdvice.invoke.after  arg:" + arguments[0]);
		return proceed;
	}

}

    7.配置实现的配置文件

<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<!-- 前置增强 -->
	<bean id="beforeAdvice" class="advice.advice.BeforeAdvice"></bean>
	<!-- 后置增强 -->
	<bean id="afterAdvice" class="advice.advice.AfterAdvice"></bean>
	<!-- 环绕增强 -->
	<bean id="aroundAdvice" class="advice.advice.AroundAdvice"></bean>
	<!-- 增强的对象 -->
	<bean id="target" class="advice.advice.FooImpl"></bean>



	<bean id="foo" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="advice.advice.Foo" p:target-ref="target"
		p:interceptorNames="beforeAdvice,afterAdvice,aroundAdvice" />


</beans>    

    8.测试代码

package advice.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {

	public static void main(String[] args) {
		System.out.println("------xml配置风格实现之前增强-------");
		// ----------xml文件方式实现前置增强
		// 文件路径
		String path = "config/advice-advice.xml";
		// 加载配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext(path);
		// 获取Bena对象
		Foo fooXml = (Foo) context.getBean("foo");
		// 调用play方法,查看是否实现前置通知
		fooXml.play("jing");
		System.out.println("------java风格实现之前增强-------");
		// ----- 实现接口方式实现前置增强
		// 创建增强的兑仓
		Foo foo = new FooImpl();
		// 创建前置增强的接口,切入点
		// 这里可以实现多个增强的切入点
		BeforeAdvice beforeAdvice = new advice.advice.BeforeAdvice();
		// 创建增强的代理器
		ProxyFactory proxyFactory = new ProxyFactory();
		// 设置代理目标
		proxyFactory.setTarget(foo);
		// 添加代理切口,可以添加多个切口
		proxyFactory.addAdvice(beforeAdvice);
		// 获取代理的器放回的对象
		Foo fooAdvice = (Foo) proxyFactory.getProxy();
		// 调用play方法,查看是否实现前置通知
		fooAdvice.play("gaosi");

		System.out.println("------后置增强增强-------");
		// -------后置增强
		// 切入后置增强的切入点
		AfterReturningAdvice afterReturningAdvice = new AfterAdvice();
		// 增加切入点
		proxyFactory.addAdvice(afterReturningAdvice);
		// 获取添加增强后的对象
		Foo afterAdviceFoo = (Foo) proxyFactory.getProxy();
		afterAdviceFoo.play("lg");

		System.out.println("-----环绕增强------");
		// 创建环绕增强的切面
		MethodInterceptor around = new AroundAdvice();
		// 添加环绕增强的切点
		proxyFactory.addAdvice(around);
		// 获取增加切点的对象
		Foo aroundFoo = (Foo) proxyFactory.getProxy();
		aroundFoo.play("jl");

	}

}

 运行结果



 10.Introdutions引介增强:
    Introdutions是允许一个切面声明一个实现指定的接口的通知对象,并且提供一个接口实现来代理这些对象。与advice的区别在于,advice是方法级别的增强,Introdutions是类级别的增强。

可以参考 introdutions增强
 

  • 大小: 210 KB
  • 大小: 128.9 KB
  • 大小: 7.8 KB
  • 大小: 34.3 KB
分享到:
评论

相关推荐

    ssh2登陆+spring aop做拦截

    SSH2 登录与 Spring AOP 拦截是两种在 IT 领域中常见的技术,主要用于提升系统安全性和管理效率。SSH2(Secure Shell version 2)是一种网络协议,用于提供安全的远程登录和数据传输,而 Spring AOP(Aspect ...

    SSH整合:spring3.2+strut2.3.4+hibernate4.2所需jar包

    8. **优势**:SSH整合的优势在于,Spring的DI和AOP可以提高代码的可测试性和可维护性;Struts2提供了强大的MVC支持,简化了前端页面与后台的交互;而Hibernate则简化了数据库操作,使得开发者可以专注于业务逻辑。 ...

    spring切面AOP所使用的jar包

    - 配置Spring AOP:在Spring配置文件中启用AOP支持,并配置切入点表达式。 - 定义切面:创建一个类作为切面,定义通知方法,并使用注解@Aspect来标识。 - 配置通知:使用@Before、@After、@AfterReturning、@...

    spring学习之六“AOP使用spring静态配置文件的实现”

    在Spring的XML配置文件中,我们需要定义`&lt;aop:config&gt;`元素来开启AOP支持,然后创建`&lt;aop:aspect&gt;`元素来定义切面。切点通常通过`&lt;aop:pointcut&gt;`定义,并通过`id`属性给它命名。通知则通过`&lt;aop:before&gt;`、`&lt;aop:...

    ssh-aop笔记

    SSH-AOP笔记主要涵盖的是Spring、Struts和Hibernate三大框架集成使用时,如何结合Aspect Oriented Programming(面向切面编程)的理念进行应用增强。在Java企业级开发中,SSH是常用的MVC架构,而AOP则是一种编程范式...

    SSH总结之Spring

    ### SSH总结之Spring详解 #### 一、Spring框架概述 Spring框架是一个开源的轻量级企业级应用框架,主要由核心容器、数据访问/集成、Web、AOP(面向切面编程)、工具、测试、消息和REST等功能模块组成。Spring的核心...

    SSH学习记录(4)-AOP测试

    标题中的"SSH学习记录(4)-AOP测试"指的是在软件开发中对Spring、Struts和Hibernate这三大框架(简称SSH)的第四部分学习,主要关注的是AOP(面向切面编程)的测试方面。AOP是编程的一种设计模式,它允许程序员定义...

    SSH例子+AOP例子

    在IT行业中,SSH和AOP是两个非常重要的概念,尤其在Java开发领域。SSH是指Spring、Struts和Hibernate这三个开源框架的首字母缩写,它们分别负责应用的依赖注入、MVC模式实现以及对象关系映射。AOP则是面向切面编程,...

    SSH笔记-AOP

    在不使用注解的情况下,可以在Spring的配置文件中通过&lt;aop:config&gt;和&lt;aop:advisor&gt;元素来声明切面。这种方式需要显式地定义切点表达式、通知类型以及通知的执行逻辑。 6. **AOP的应用场景** - **事务管理**:...

    Spring AOP学习笔记

    NULL 博文链接:https://linres.iteye.com/blog/281221

    spring 配置aop时需要的jar包

    2. 开启AOP代理:在Spring配置文件中,通过`&lt;aop:config&gt;`标签开启AOP支持,并可以定义切入点表达式(pointcut expression)和通知类型。 3. 定义切面:你可以使用Spring的`@Aspect`注解来定义一个切面类,然后在类...

    ssh添加aop配置

    SSH(Spring、Struts2、Hibernate)是一个经典的Java Web开发框架,它整合了Spring的IoC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)功能,Struts2作为MVC(Model-View-...

    spring_AOP.rar_876.aop_java aop_spring_aop

    1. 静态代理(XML定义):通过Spring的`&lt;aop:config&gt;`标签来配置切面,包括定义切入点表达式和通知类型。 2. 动态代理(基于注解):使用`@Aspect`注解定义切面,`@Before`、`@After`、`@Around`等注解定义通知,...

    SSH学习之spring

    【SSH架构学习之Spring】 SSH(Struts、Spring、Hibernate)是Java开发中常见的三大框架组合,用于构建企业级Web应用程序。在这个主题中,我们主要关注Spring框架的学习。Spring作为一个全面的企业级应用开发框架,...

    SSH 配置实例: Spring 3.1 + Hibernate 4.2 + Struts 2.3

    SSH(Spring、Struts、Hibernate)是Java Web开发中经典的三大框架组合,它们协同工作,构建出高效、灵活的企业级应用程序。在这个配置实例中,我们将深入探讨如何将Spring 3.1、Hibernate 4.2和Struts 2.3整合在...

    SSH和Spring框架简介

    SSH和Spring框架是Java开发中的两个重要工具,它们在企业级应用开发中占据了核心地位。SSH,是由Struts2、Spring和Hibernate三个框架组成的集成解决方案,而Spring则是一个全面的后端开发框架,包含了多种功能模块。...

    SSH+AOP学习资料源码

    通过学习和实践这些SSH+AOP的资料源码,开发者可以提升自己在Java Web开发领域的技能,理解如何利用Spring管理依赖,使用Struts处理Web请求,借助Hibernate操作数据库,以及如何运用AOP来增强代码的灵活性和可维护性...

    SSH中Spring所需基本jar包

    SSH(Struts、Spring、Hibernate)是一个经典的Java Web开发框架组合,其中Spring是核心,它负责管理和协调应用程序的各个部分。本资源提供了Spring框架所需的基本jar包,这些jar包是构建基于Spring的应用程序的基础...

    SSH框架:struts2+spring+hibernate 全部jar包

    SSH框架是Java开发中常用的三大框架集成,包括Struts2、Spring和Hibernate。这个压缩包提供了搭建SSH框架所需的所有jar包和配置文件,使得开发者能够快速构建基于这三大框架的应用。 Struts2作为MVC(Model-View-...

    对Spring的AOP标签的支持

    4. `&lt;aop:before&gt;`、`&lt;aop:after&gt;`、`&lt;aop:around&gt;`、`&lt;aop:after-returning&gt;`、`&lt;aop:after-throwing&gt;`:这些标签分别定义了在目标方法执行前、执行后(无论是否抛出异常)、环绕执行、正常返回后和抛出异常后执行...

Global site tag (gtag.js) - Google Analytics