Spring之aop

目录

一,AOP的概念(即面向切面编程)

    1,目标(Target)

    2,通知(Advice)

    3   代理(Proxy )

    4   切入点(Pointcut)

    5   适配器(Advisor)

    6   连接点(Joinpoint)

 二:主要通知

1.前置通知

2.后置通知

3.环绕通知

4.异常通知

5.过滤通知


一,AOP的概念(即面向切面编程)


    1,目标(Target)


                被通知(被代理)的对象

    2,通知(Advice)


                在某个特定的连接点上执行的动作,同时Advice也是程序代码的具体实现,例如一个实现日志记录的代码(通知有些书上也称为处理)

    3   代理(Proxy )


                将通知应用到目标对象后创建的对象(代理=目标+通知),只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的

    4   切入点(Pointcut)


                多个连接点的集合,定义了通知应该应用到那些连接点。
                 (也将Pointcut理解成一个条件 ,此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序)

    5   适配器(Advisor)


                适配器=通知(Advice)+切入点(Pointcut)

    6   连接点(Joinpoint)


                程序执行过程中明确的点,如方法的调用,或者异常的抛出.
 

 二:主要通知

1.前置通知

<!-- 目标对象 -->
	<bean class="com.zking.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>
	<!-- 前置通知 -->
	<bean class="com.zking.aop.advice.MyMethodBeforeAdvice" id="myBefore"></bean>
	<!-- 代理对象=目标+通知 -->
	<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
		<!-- 目标 -->
		<property name="target" ref="bookBiz"></property>
		<!-- 目标所实现的接口列表 -->
		<property name="proxyInterfaces">
			<list>
				<value>com.zking.aop.biz.BookBiz</value>
			</list>
		</property>
		<!-- 通知:正式调用目标方法的时候,会调用下面指定的通知 -->
		<property name="interceptorNames">
			<list>
				<value>myBefore</value>
			</list>
		</property>
	</bean>
package com.zking.aop.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.MethodBeforeAdvice;

/**
 * 前置通知
 *	买书、评论前加系统日志
 * @author Administrator
 *
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice{

	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
//		目标对象的类名
		String clzName = arg2.getClass().getName();
//		当前调用的方法是
		String methodName = arg0.getName();
//		当前调用方法所传递参数
		String args = Arrays.toString(arg1);
		System.out.println("【系统日志】:"+clzName+"."+methodName+"被调用,传递的参数为:"+args);
	}
	
}

package com.zking.aop.biz;

public interface BookBiz {
	// 购书
	public boolean buy(String userName, String bookName, Double price);

	// 发表书评
	public void comment(String userName, String comments);
}

package com.zking.aop.biz.impl;

import com.zking.aop.biz.BookBiz;
import com.zking.aop.exception.PriceException;

public class BookBizImpl implements BookBiz {

	public BookBizImpl() {
		super();
	}

	public boolean buy(String userName, String bookName, Double price) {
		// 通过控制台的输出方式模拟购书
		if (null == price || price <= 0) {
			throw new PriceException("book price exception");
		}
//		logDao.add->sout("买书相关日志...")
		System.out.println(userName + " buy " + bookName + ", spend " + price);
		return true;
	}

	public void comment(String userName, String comments) {
		// 通过控制台的输出方式模拟发表书评
		System.out.println(userName + " say:" + comments);
	}

}

package com.zking.aop.exception;

public class PriceException extends RuntimeException {

	public PriceException() {
		super();
	}

	public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public PriceException(String message, Throwable cause) {
		super(message, cause);
	}

	public PriceException(String message) {
		super(message);
	}

	public PriceException(Throwable cause) {
		super(cause);
	}
	
}

package com.zking.aop.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.zking.aop.biz.BookBiz;

public class Demo1 {
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
//		BookBiz bean = (BookBiz)context.getBean("bookBiz");
		BookBiz bean = (BookBiz)context.getBean("bookProxy");
		bean.buy("nx", "jpm", 6.6d);
		bean.comment("sfd", "asd");
	}
}

2.后置通知

<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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:context="http://www.springframework.org/schema/context"
	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-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<!-- IOC的主要作用管理整个项目的javabean,依靠依赖注入、控制反转的特点进行管理 -->
	<bean class="com.zking.biz.impl.UserBizImpl1" id="userBiz"></bean>
	<!-- <bean class="com.zking.biz.impl.UserBizImpl2" id="userBiz"></bean> -->
	<!-- set注入 -->
	<bean class="com.zking.web.UserAction" id="userAction">
		<property name="userBiz" ref="userBiz"></property>
		<property name="age" value="22"></property>
		<property name="name" value="zhangsan"></property>
		<property name="hobby">
			<list>
				<value>篮球</value>
				<value>boy</value>
				<value>篮球</value>
			</list>
		</property>
	</bean>
	<!-- 构造注入 -->
	<bean class="com.zking.web.OrderAction" id="orderAction">
		<property name="userBiz" ref="userBiz"></property>
		<constructor-arg name="name" value="zhangsan"></constructor-arg>
		<constructor-arg name="age" value="22"></constructor-arg>
		<constructor-arg name="hobby">
			<list>
				<value>篮球</value>
				<value>boy</value>
				<value>篮球</value>
			</list>
		</constructor-arg>
	</bean>
	
	<!-- 目标对象 -->
	<bean class="com.zking.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>
	<!-- 前置通知 -->
	<bean class="com.zking.aop.advice.MyMethodBeforeAdvice" id="myBefore"></bean>
	<!-- 后置通知 -->
	<bean class="com.zking.aop.advice.MyAfterReturningAdvice" id="myAfter"></bean>
	<!-- 代理对象=目标+通知 -->
	<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
		<!-- 目标 -->
		<property name="target" ref="bookBiz"></property>
		<!-- 目标所实现的接口列表 -->
		<property name="proxyInterfaces">
			<list>
				<value>com.zking.aop.biz.BookBiz</value>
			</list>
		</property>
		<!-- 通知:正式调用目标方法的时候,会调用下面指定的通知 -->
		<property name="interceptorNames">
			<list>
				<value>myBefore</value>
				<value>myAfter</value>
			</list>
		</property>
	</bean>
	
</beans>

package com.zking.aop.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.zking.aop.biz.BookBiz;

public class Demo1 {
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
//		BookBiz bean = (BookBiz)context.getBean("bookBiz");
		BookBiz bean = (BookBiz)context.getBean("bookProxy");
		bean.buy("nx", "jpm", 6.6d);
		bean.comment("sfd", "asd");
	}
}

package com.zking.aop.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.AfterReturningAdvice;

public class MyAfterReturningAdvice implements AfterReturningAdvice{

	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
//		目标对象的类名
		String clzName = arg3.getClass().getName();
//		当前调用的方法是
		String methodName = arg1.getName();
//		当前调用方法所传递参数
		String args = Arrays.toString(arg2);
		System.out.println("【买书返利】:"+clzName+"."+methodName+"被调用,传递的参数为:"+args+";目标对象方法返回值为:"+arg0);
	}

}

3.环绕通知

package com.zking.aop.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.zking.aop.biz.BookBiz;

public class Demo1 {
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
//		BookBiz bean = (BookBiz)context.getBean("bookBiz");
		BookBiz bean = (BookBiz)context.getBean("bookProxy");
		bean.buy("nx", "jpm", 6.6d);
		bean.comment("sfd", "asd");
	}
}

package com.zking.aop.advice;

import java.util.Arrays;

import org.aopalliance.intercept.MethodInvocation;

/**
 * 环绕通知=前置通知+后置通知
 * @author Administrator
 *
 */
public class MethodInterceptor implements org.aopalliance.intercept.MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
//		目标对象的类名
		String clzName = arg0.getThis().getClass().getName();
//		当前调用的方法是
		String methodName = arg0.getMethod().getName();
//		当前调用方法所传递参数
		String args = Arrays.toString(arg0.getArguments());
		System.out.println("【环绕通知】:"+clzName+"."+methodName+"被调用,传递的参数为:"+args);
//		方法的返回值	执行目标方法	bookBiz.buy(as,jasd,6.6);
		Object rs = arg0.proceed();
		System.out.println("【环绕通知】:目标对象方法返回值为:"+rs);
		return rs;
	}

}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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:context="http://www.springframework.org/schema/context"
	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-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<!-- IOC的主要作用管理整个项目的javabean,依靠依赖注入、控制反转的特点进行管理 -->
	<bean class="com.zking.biz.impl.UserBizImpl1" id="userBiz"></bean>
	<!-- <bean class="com.zking.biz.impl.UserBizImpl2" id="userBiz"></bean> -->
	<!-- set注入 -->
	<bean class="com.zking.web.UserAction" id="userAction">
		<property name="userBiz" ref="userBiz"></property>
		<property name="age" value="22"></property>
		<property name="name" value="zhangsan"></property>
		<property name="hobby">
			<list>
				<value>篮球</value>
				<value>boy</value>
				<value>篮球</value>
			</list>
		</property>
	</bean>
	<!-- 构造注入 -->
	<bean class="com.zking.web.OrderAction" id="orderAction">
		<property name="userBiz" ref="userBiz"></property>
		<constructor-arg name="name" value="zhangsan"></constructor-arg>
		<constructor-arg name="age" value="22"></constructor-arg>
		<constructor-arg name="hobby">
			<list>
				<value>篮球</value>
				<value>boy</value>
				<value>篮球</value>
			</list>
		</constructor-arg>
	</bean>
	
	<!-- 目标对象 -->
	<bean class="com.zking.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>
	<!-- 前置通知 -->
	<bean class="com.zking.aop.advice.MyMethodBeforeAdvice" id="myBefore"></bean>
	<!-- 后置通知 -->
	<bean class="com.zking.aop.advice.MyAfterReturningAdvice" id="myAfter"></bean>
	<!-- 环绕通知 -->
	<bean class="com.zking.aop.advice.MethodInterceptor" id="myMethod"></bean>
	<!-- 代理对象=目标+通知 -->
	<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
		<!-- 目标 -->
		<property name="target" ref="bookBiz"></property>
		<!-- 目标所实现的接口列表 -->
		<property name="proxyInterfaces">
			<list>
				<value>com.zking.aop.biz.BookBiz</value>
			</list>
		</property>
		<!-- 通知:正式调用目标方法的时候,会调用下面指定的通知 -->
		<property name="interceptorNames">
			<list>
				<value>myBefore</value>
				<value>myAfter</value>
				<value>myMethod</value>
			</list>
		</property>
	</bean>
	
</beans>

4.异常通知

package com.zking.aop.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.zking.aop.biz.BookBiz;

public class Demo1 {
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
//		BookBiz bean = (BookBiz)context.getBean("bookBiz");
		BookBiz bean = (BookBiz)context.getBean("bookProxy");
		bean.buy("nx", "jpm", -6.6d);
		bean.comment("sfd", "asd");
	}
}

package com.zking.aop.advice;

import org.springframework.aop.ThrowsAdvice;

import com.zking.aop.exception.PriceException;

/**
 * 关于过滤通知
 * 	相较于前置通知、后置通知、环绕通知有一个非常大的区别
 * 	前面三大通知都需要实现其中的方法
 * 	环绕通知则不需要,但是,它的方法名又是固定的;
 * @author Administrator
 *
 */
public class MyThrowsAdvice implements ThrowsAdvice{
	public void after(PriceException p) {
		System.out.println("【异常通知】:当价格发生异常,那么执行此处代码块!!!");
	}
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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:context="http://www.springframework.org/schema/context"
	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-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<!-- IOC的主要作用管理整个项目的javabean,依靠依赖注入、控制反转的特点进行管理 -->
	<bean class="com.zking.biz.impl.UserBizImpl1" id="userBiz"></bean>
	<!-- <bean class="com.zking.biz.impl.UserBizImpl2" id="userBiz"></bean> -->
	<!-- set注入 -->
	<bean class="com.zking.web.UserAction" id="userAction">
		<property name="userBiz" ref="userBiz"></property>
		<property name="age" value="22"></property>
		<property name="name" value="zhangsan"></property>
		<property name="hobby">
			<list>
				<value>篮球</value>
				<value>boy</value>
				<value>篮球</value>
			</list>
		</property>
	</bean>
	<!-- 构造注入 -->
	<bean class="com.zking.web.OrderAction" id="orderAction">
		<property name="userBiz" ref="userBiz"></property>
		<constructor-arg name="name" value="zhangsan"></constructor-arg>
		<constructor-arg name="age" value="22"></constructor-arg>
		<constructor-arg name="hobby">
			<list>
				<value>篮球</value>
				<value>boy</value>
				<value>篮球</value>
			</list>
		</constructor-arg>
	</bean>
	
	<!-- 目标对象 -->
	<bean class="com.zking.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>
	<!-- 前置通知 -->
	<bean class="com.zking.aop.advice.MyMethodBeforeAdvice" id="myBefore"></bean>
	<!-- 后置通知 -->
	<bean class="com.zking.aop.advice.MyAfterReturningAdvice" id="myAfter"></bean>
	<!-- 异常通知 -->
	<bean class="com.zking.aop.advice.MyThrowsAdvice" id="myThrows"></bean>
	<!-- 环绕通知 -->
	<bean class="com.zking.aop.advice.MethodInterceptor" id="myMethod"></bean>
	<!-- 代理对象=目标+通知 -->
	<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
		<!-- 目标 -->
		<property name="target" ref="bookBiz"></property>
		<!-- 目标所实现的接口列表 -->
		<property name="proxyInterfaces">
			<list>
				<value>com.zking.aop.biz.BookBiz</value>
			</list>
		</property>
		<!-- 通知:正式调用目标方法的时候,会调用下面指定的通知 -->
		<property name="interceptorNames">
			<list>
				<value>myBefore</value>
				<value>myAfter</value>
				<value>myMethod</value>
				<value>myThrows</value>
			</list>
		</property>
	</bean>
	
</beans>

5.过滤通知

package com.zking.aop.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.zking.aop.biz.BookBiz;

public class Demo1 {
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
//		BookBiz bean = (BookBiz)context.getBean("bookBiz");
		BookBiz bean = (BookBiz)context.getBean("bookProxy");
		bean.buy("nx", "jpm", 6.6d);
		bean.comment("sfd", "asd");
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值