Java框架:AOP--(JDK、CGLIB)

Spring对AOP的支持

Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:
1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了
2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB	


CGLIB例子

目标类:

package com.aop.cglib;

public class UserService{

	public void buy(String name) {
		System.out.println(name+",买好洗衣粉,回家洗衣服去了..CGLib");
	}

}
织入类

package com.aop.cglib;
import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;


/**
 * CGLib用底层字节码技术,可以为一个类创建子类,并子类中采用方法拦截技术"拦截"所以父类方法的调用,并且顺势"织入"我们需要的业务"逻辑代码".
 * 简语--当一个类继承了cgblib类以后,实现类MethodInterceptor,在目标对象对象方法的时候就是进行拦截,并且织入逻辑代码
 */

public class CglibProxy implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();
	
	public Object getProxy(Class clz) {
		enhancer.setSuperclass(clz);//设置创建子类的类,目标类
		enhancer.setCallback(this);
		return enhancer.create();//才用底层字节码技术,创建对象
	}
	
	@Override
	//拦截所以业务的方法--代理类代用的方法
	public Object intercept(Object obj, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
		System.out.println("走到了收银台付钱了...CGLib");//织入横切业务逻辑
		Object result = methodProxy.invokeSuper(obj, params);//执行代理类调用的方法
		System.out.println("登记一下账目CGLib");//织入横切业务逻辑
		return null;//返回对象
	}

	
}
测试类

package com.aop.cglib;

public class Test {

	public static void main(String[] args) {
		//这个代理对象
		CglibProxy proxy = new CglibProxy();
		UserService userService = (UserService) proxy.getProxy(UserService.class);
		
		userService.buy("mm");
	}
}


JDK例子

接口:

package com.aop.jdk;

public interface IUserService {

	public void buy(String name);
}
目标类:

package com.aop.jdk;

public class UserService implements IUserService{

	@Override
	public void buy(String name) {
		System.out.println(name+",买好洗衣粉,回家洗衣服去了..JDK");
	}
}

织入类

package com.aop.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class WavingInvocationHandler implements InvocationHandler{
	
	private Object target;
	
	public WavingInvocationHandler(Object target) {
		super();
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
		System.out.println("走到了收银台付钱了...JDK");
		Object obj = method.invoke(target, params);
		System.out.println("登记一下账目JDK");
		return obj;
	}

}

测试类:

package com.aop.jdk;

import java.lang.reflect.Proxy;

public class Test {

	public static void main(String[] args) {
		/** Aop
			---jdk动态"代理"
			1:目标对象
			2:织入类
			3:代理类
			4:接口
			---CGLIB动态"代理"
			1:目标对象
			2:织入类
			3:代理类
		 */
		//目标类
		IUserService userService = new UserService();
		//织入类
		WavingInvocationHandler handler = new WavingInvocationHandler(userService);
		//代理类--增强的对象--proxyUser -代理商
		IUserService proxyUser = (IUserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
				userService.getClass().getInterfaces(), handler);
		
		proxyUser.buy("MM");
	}
}



简单的spring  AOP

接口:

package com.aop.spring;

public interface IWaiter {

	public void sayHello(String name);

	public void server(String name);
}

目标类:

package com.aop.spring;

public class WaiterImpl implements IWaiter{

	@Override
	public void sayHello(String name) {
		System.out.println("你好!"+name);
	}

	@Override
	public void server(String name) {
		System.out.println("服务于:"+name);
	}

}

前置通知类

package com.aop.spring;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class GreetingBeforeAdvice implements MethodBeforeAdvice{

	@Override
	public void before(Method method, Object[] params, Object obj) throws Throwable {
		String name = String.valueOf(params[0]);
		System.out.println("早上好,"+name+",睡的可好");
	}

}

bean.xml文件

<?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:tx="http://www.springframework.org/schema/tx" 
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:context="http://www.springframework.org/schema/context" 
		xmlns:jee="http://www.springframework.org/schema/jee"
		xmlns:p="http://www.springframework.org/schema/p" 
		xsi:schemaLocation="
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd" >
			
		<!-- (advice增强类) -->
		<bean id="advice" class="com.aop.spring.GreetingBeforeAdvice"></bean>
		<!-- 目标类 -->	
		<bean id="target" class="com.aop.spring.WaiterImpl"></bean>
		<!-- 代理工厂 -->
		<!--
		
			通过设定:optimize来决定你是否使用的代理模式:
			true:cglib动态代理
			false:jdk的动态代理(默认)
			当设置true的时候:强制使用cgblib代理,对应单例模式,推荐使用它。dao,service,
			对已其他的模式,一般推荐使用jdk的代理。原因是cglib,在创建代理对象的时候,是编译阶段发生的行为,而创建出的对象对象的运行速度较高。
			jdk代理恰好相反。
			
			单例模式就用:cgblib
			多例模式都用:jdk
			
			SpringAop:的底层就是通过JDK动态代理"或"CGLib动态代理为技术目标织入横切逻辑。
			做aop:需要导入:
			spring-aop-4.1.5.RELEASE.jar
			spring-beans-4.1.5.RELEASE.jar
			spring-context-4.1.5.RELEASE.jar
			spring-context-support-4.1.5.RELEASE.jar
			spring-core-4.1.5.RELEASE.jar
			
			cglib引入的包:
			cglib-nodep-2.1_3.jar
			
			aop联盟:schmeAop
			aopalliance-1.0.jar
			aspectj:基于注解aop
			aspectjweaver.jar
			
			org.springframework.aop.MethodBeforeAdvice 前置通知:在目标方法之前,执行的业务逻辑 :MethodBeforeAdvice
			org.springframework.aop.AfterReturningAdvice 后置通知:在目标方法之后,执行的业务逻辑
			org.aopalliance.intercept.MethodInterceptor 环绕通知:目标方法执行前后,执行的业务逻辑(用的最多的)
			org.springframework.aop.ThrowsAdvice 异常通知:执行目标方法出现异常,执行的业务逻辑(几乎很少使用)
			org.springframework.aop.IntroductionInterceptor 引介通知.在目标类中添加了一些新的方法和属性的时候,执行的业务逻辑(几乎很少使用)
			
			Aop:注解
			schemeaop
			
			服务员和顾客问好和服务.
			1:早上好.XXX sayHello(String name)
			2:对XXX提供服务. server(String name)
			
			//采用spring的jdk动态代理
			 * 1:接口
			 * 2:织入类(通知类)
			 * 3:目标类
			 * 4:代理类
		 -->
		<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"
			p:proxyInterfaces="com.aop.spring.IWaiter"
			p:interceptorNames="advice"
			p:target-ref="target"
			p:proxyTargetClass="true">
		</bean>
	
</beans>

测试类:

package com.aop.spring;

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

public class Test {

	/**
	 * SpringAop:的底层就是通过JDK动态代理"或"CGLib动态代理为技术目标织入横切逻辑。
	 * 做aop:需要导入:
	 *  spring-aop-4.1.5.RELEASE.jar
		spring-beans-4.1.5.RELEASE.jar
		spring-context-4.1.5.RELEASE.jar
		spring-context-support-4.1.5.RELEASE.jar
		spring-core-4.1.5.RELEASE.jar
		
		cglib引入的包:
		cglib-nodep-2.1_3.jar
	
		aop联盟:schmeAop
		aopalliance-1.0.jar
		aspectj:基于注解aop
		aspectjweaver.jar
		
		org.springframework.aop.MethodBeforeAdvice 前置通知:在目标方法之前,执行的业务逻辑 :MethodBeforeAdvice
		org.springframework.aop.AfterReturningAdvice 后置通知:在目标方法之后,执行的业务逻辑
		org.aopalliance.intercept.MethodInterceptor 环绕通知:目标方法执行前后,执行的业务逻辑(用的最多的)
		org.springframework.aop.ThrowsAdvice 异常通知:执行目标方法出现异常,执行的业务逻辑(几乎很少使用)
		org.springframework.aop.IntroductionInterceptor 引介通知.在目标类中添加了一些新的方法和属性的时候,执行的业务逻辑(几乎很少使用)
		
		Aop:注解
		schemeaop
		
		服务员和顾客问好和服务.
		1:早上好 XXX  sayHello(String name)
		2:对XXX提供服务. server(String name)
		
		//采用spring的jdk动态代理
		 * 1:接口
		 * 2:织入类(通知类)
		 * 3:目标类
		 * 4:代理类
	 */
	
	
	public static void main(String[] args) {
		
		//获取代理对象(目标对象的增强对象)
		ApplicationContext context = new ClassPathXmlApplicationContext("classpath:com/aop/spring/bean.xml");
//		ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//		WaiterImpl waiterImpl = (WaiterImpl) context.getBean("proxy");
		IWaiter waiterImpl = (IWaiter) context.getBean("proxy");
		waiterImpl.sayHello("MM");
		System.out.println("====================");
		waiterImpl.server("FF");
	}
}






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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值