小菜鸟 SSM框架之 Spring复习-04(AOP-AspectJ-中)

基于代理类的AOP实现

spring中的AOP代理默认就是使用JDK动态代理实现的。在spring中使用ProxyFactoryBean 是创建AOP代理的最基本的方式(需要导入aop 和aoplliance两个包)

Spring 的通知类型

spring的通知按照是在目标类方法连接点的位置可分为一下五种:

通知类型说明
(环绕通知) org.aopllance.intercept.MethodInterceptor在目标方法执行前后实施增强,可用于日志和事务管理等功能
(前置通知)org.springframework.aop.MethodBeforeAdvice在目标方法执行前实施增强,可用于权限管理等功能
(后置通知) org.springframework.aop.AfterReturningAdvice在目标方法执行后实施增强,可用于关闭流、上传文件、删除文件等功能
(异常通知)org.springframework.aop.ThrowsAdvice在方法抛出异常后实施增强,可用于处理异常记录日志
(引介通知) org.springframework.aop.IntroductionInterceptor在目标类中添加一些新的方法和属性,用于修改老版本的程序

ProxyFactoryBean

ProxyFactoryBeanFactoryBean 接口的实现类 。FactoryBean 负责实例化一个Bean,ProxyfactoryBean 负责为其他Bean 创建代理实例。

ProxyFactoryBean常用的属性

属性名称描述
target代理的目标对象
proxyInterfaces (汉语:代理接口)代理实现的接口。多个接口可用以下形式:
proxyTargetClass是否使用CGLIB代理,为true时,使用CGLIB代理
interceptorNames (汉语:拦截器)需要织入目标的Advice (即创建的切面类)
singleton返回代理是否是单例,默认为true(返回单例实例)
optimize当设置为true时,强制使用CGLIB代理

案例以环绕通知为例:

创建一个切面类 :

package com.itheima.proxyfactorybean;

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

//切面类
public class MyAspect implements MethodInterceptor {

	public Object invoke(MethodInvocation methodInvocation) throws Throwable {
		
		check_Permission();
		//执行目标方法
		Object obj = methodInvocation.proceed();
		log();
		return obj;
		
	}

	private void log() {
		System.out.println("模拟记录日志。。。。");
	}

	private void check_Permission() {
		System.out.println("模拟检查权限。。。。");
	}
}

切面类继承了org.aopllance.intercept.MethodInterceptor(环绕通知)接口,并实现接口中的invoke()方法。

创建配置文件 applicationContext.xml: (ProxyFactoryBean的重要内容是配置文件的配置)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

     <!-- 目标类 -->
     <bean id = "userDao" class = "com.itheima.proxyfactorybean.UserDaoImpl"></bean>
     <!-- 切面类 -->
     <bean id = "myAspect" class = "com.itheima.proxyfactorybean.MyAspect"></bean>
     
     <!-- 使用Spring代理工厂定义一个名称为UserDaoProxy的代理对象 -->
     <bean id = "userDaoProxy" class = "org.springframework.aop.framework.ProxyFactoryBean">
     	<!-- 指定代理实现的接口 -->
     	<property name="proxyInterfaces" value = "com.itheima.proxyfactorybean.UserDao"></property>
     	<!-- 指定目标对象 -->
     	<property name="target" ref = "userDao"></property>
     	<!-- 指定切面  植入环绕通知 -->
     	<property name="interceptorNames" value = "myAspect"></property>
     	<!-- 指定代理模式  ture 使用cglib  false(默认)  jdk 动态代理 -->
     	<property name="proxyTargetClass"  value  = "true"></property>
     </bean>
 
</beans>

在定义代理对象时,通过子元素指定了代理实现的接口、代理的目标对象、需要织入的目标类的通知(即切面类)、代理方式

创建测试类ProxyFatoryBeanTest:

package com.itheima.proxyfactorybean;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.junit.Test;
import org.springframework.context.ApplicationContext;

public class ProxyFactoryBeanTest {
	@Test
	public  void MyTest(){
		String xmlPath = "com/itheima/proxyfactorybean/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		UserDao userDao = (UserDao) applicationContext.getBean("userDaoProxy");
		userDao.addUser();
		userDao.deleteUser();
		((AbstractApplicationContext)applicationContext).close();
	}
}


			在校学习生,不定时更新。还请各位看官谅解。
(参考书籍:JAVA EE 企业级应用开发教程(Spring+SpringMVC+MyBatis))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值