Spring aop 基于schema的AOP支持及JoinPoint的使用、如何使用CGLIB代理

 基于schema的aop只是将配置写到配置文件中。

代码:

package com.lwf.aop;

public interface UserManager {

	public void add(String name, String password);
	public void del(String id);
	public void modify(int id ,String name, String password);
}

 

package com.lwf.aop;

public class UserManagerImpl implements UserManager {

	public void add(String name, String password) {

		System.out.println("add method");
	}

	public void del(String id) {
		System.out.println("del method");
	}

	public void modify(int id, String name, String password) {
		System.out.println("modify method");
	}

}

 

package com.lwf.aop;

public interface MySecurityManager {

	public void checkSecurity();
}

 

package com.lwf.aop;

public class MySecurityManagerImpl implements MySecurityManager {
	public void checkSecurity() {
		System.out.println("User security Check");
	}

}

 

注意上面的实现类中没有做任何@AspectJ的声明。

配置文件:

<?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"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
		
>
	
	<bean id="userManager" class="com.lwf.aop.UserManagerImpl"></bean>
	<bean id="mySecurityManager" class="com.lwf.aop.MySecurityManagerImpl"></bean>
	<aop:config>
		<aop:aspect id="mySecurity" ref="mySecurityManager">
			<aop:pointcut expression="execution(* add*(..)) || execution(* del*(..))" id="allAddMethod" />
			<aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>
		</aop:aspect>
	</aop:config>
</beans>

 

测试类:

package com.lwf.aop;

import junit.framework.TestCase;

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

public class Client extends TestCase{

	public void testAop(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserManager userManager = (UserManager)ac.getBean("userManager");
		userManager.add("zhangshang", "123456");
		userManager.del("23");
	}
}

 结果:

 

User security Check
add method
User security Check
del method

 注意我们配置文件中删除了:<aop:aspectj-autoproxy/>

 

JoinPoint的使用

在上面的checkSecurity方法中,我们没办法得到横切对象方法如add方法的参数。我们使用JoinPoint来解决。

上面示例只需要修改对应的checkSecurity方法即可。如我们修改MySecurityManagerImpl如下:

package com.lwf.aop;

import org.aspectj.lang.JoinPoint;

public class MySecurityManagerImpl implements MySecurityManager {
	public void checkSecurity(JoinPoint joinPoint) {
		 Object args[] = joinPoint.getArgs();
		 if(args!=null){
			for (int i = 0; i < args.length; i++) {
				System.out.println("args[" +i+"] =" + args[i]);
			}
		 }
		System.out.println("User security Check");
	}

}

 

我们通过给checkSecurity方法增加JoinPoint joinPoint参数,再通过getArgs方法得到add方法的参数。

现在测试Client.java

 

package com.lwf.aop;

import junit.framework.TestCase;

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

public class Client extends TestCase{

	public void testAop(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserManager userManager = (UserManager)ac.getBean("userManager");
		userManager.add("zhangshang", "123456");
		//userManager.del("23");
	}
}

 

输出如下:

args[0] =zhangshang
args[1] =123456
User security Check
add method

 

我们看到获取了用户名和密码。这种方法在不修改配置文件的条件下即可获得add方法参数。

 

需要注意的是因为spring aop默认采用的是J2SE实现的动态代理机制,而动态代理机制只能对接口代理,所以上面的代码UserManager必须是接口。如果不使用接口则要使用cglib代理,因为cglib代理可以对类实现代理

如何使用cglib代理?

我们可以强制让spring aop使用cglib代理而不是jdk的动态代理。

只要在配置文件中将

<aop:config proxy-target-class="true">

 并且增加cglib库到我们的用户自定义库中。

下面来测试:

我们首先删除UserManager接口,也删除MySecurityManager接口(这个接口本来就可以不要)。

修改Client的测试代码。剩下的代码如下所示。

注意我们先不使用cglib测试:

package com.lwf.aop;

public class UserManagerImpl {

	public void add(String name, String password) {

		System.out.println("add method");
	}

	public void del(String id) {
		System.out.println("del method");
	}

	public void modify(int id, String name, String password) {
		System.out.println("modify method");
	}

}

 

package com.lwf.aop;

import org.aspectj.lang.JoinPoint;

public class MySecurityManagerImpl  {
	public void checkSecurity(JoinPoint joinPoint) {
		 Object args[] = joinPoint.getArgs();
		 if(args!=null){
			for (int i = 0; i < args.length; i++) {
				System.out.println("args[" +i+"] =" + args[i]);
			}
		 }
		System.out.println("User security Check");
	}

}

 

package com.lwf.aop;

import junit.framework.TestCase;

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

public class Client extends TestCase{

	public void testAop(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		//UserManager userManager = (UserManager)ac.getBean("userManager");
		//userManager.add("zhangshang", "123456");
		//userManager.del("23");
		
		UserManagerImpl userManager = (UserManagerImpl)ac.getBean("userManager");
		userManager.add("zhangshang", "123456");
	}
}

 

<?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"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
		
>
	
	<bean id="userManager" class="com.lwf.aop.UserManagerImpl"></bean>
	<bean id="mySecurityManager" class="com.lwf.aop.MySecurityManagerImpl"></bean>
	<aop:config >
		<aop:aspect id="mySecurity" ref="mySecurityManager">
			<aop:pointcut expression="execution(* add*(..)) || execution(* del*(..))" id="allAddMethod" />
			<aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>
		</aop:aspect>
	</aop:config>
</beans>

 测试输出结果:

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'userManager' defined in class path resource [applicationContext.xml]: 
Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: 
Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.	

 我们可以看到删除UserManager接口,而默认情况下使用JDK动态代理又需要该接口,所以报错,提示在这种情况下应该要使用cglib代理。

下面我们使用cglib代理,一加入cglib库,二修改配置文件如下:

<?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"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
		
>
	
	<bean id="userManager" class="com.lwf.aop.UserManagerImpl"></bean>
	<bean id="mySecurityManager" class="com.lwf.aop.MySecurityManagerImpl"></bean>
	<aop:config proxy-target-class="true">
		<aop:aspect id="mySecurity" ref="mySecurityManager">
			<aop:pointcut expression="execution(* add*(..)) || execution(* del*(..))" id="allAddMethod" />
			<aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>
		</aop:aspect>
	</aop:config>
</beans>

 

输出结果:

args[0] =zhangshang
args[1] =123456
User security Check
add method

 

通常我们使用JDK的动态代理就可以了,一般我们是对一些之前开发的系统,因为没有接口类,所以考虑使用cglib代理进行增加spring aop 的功能。

J2SE动态代理和CGLIB字节码生成代理的区别?
	* J2SE动态代理只针对接口进行代理,不能针对类
	* CGLIB是针对类实现代理,主要对指定的类生成一个子类,并覆盖其中的方法,从而实现方法的拦截,
	  因为是通过继承,所以无法为final方法提供代理

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、可私信6博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、可私信6博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值