010_AOPXml方式开发

1. 什么是AOP?

2. Spring底层的AOP实现原理

2.1. AOP应用场景

2.2. Spring动态代理

2.2.1. JDK动态代理: 只能对实现了接口的类产生代理。

2.2.2. CGLIB动态代理: 对没有实现接口的类产生代理。CGLIB(Code Generation Library)是一个开源的, 强大的, 高性能, 高质量的Code生成类库。Spring引入了它。

3. AOP简介

3.1. AOP思想最早是由AOP联盟组织提出的。Spring是使用这种思想的最好的框架。

3.2. AspectJ是一个面向切面的框架, 它扩展了Java语言。

3.3. Spring早期的AOP是自己实现的, 但是十分繁琐。后来Spring引入了AspectJ进行AOP开发。

4. AOP术语

5. Spring中通知类型

5.1. 前置通知: 在目标方法执行之前进行操作。

5.2. 后置通知: 在目标方法执行之后进行操作。

5.3. 环绕通知: 在目标方法执行之前和之后进行操作。

5.4. 异常抛出通知: 在程序出现异常的时候进行操作。

5.5. 最终通知: 无论代理是否有异常, 总会执行。

6. 切入点表达式语法

6.1. 基于execution的函数完成的。

6.2. [访问修饰符] 返回值类型 包名.类名.方法名(参数), 访问修饰符可以省略不写。

6.3. public void com.lywgames.dao.impl.UserDaoImpl.insert(..), 参数使用.., 表示任意参数。

6.4. * com.lywgames.dao.impl.UserDaoImpl.insert(..), 返回值使用*, 表示任意返回值类型。

6.5. * com..UserDaoImpl.insert(..), 包路径可以使用..做省略, 但是必须有开头。

6.6. * com.lywgames.dao.impl.*.*(..), 该包下的所有类的所有方法。

7. 引入aop的约束

8. 切入点配置

9. 通知配置

10. JDK动态代理例子

10.1. 新建一个名为JdkProxy的Java项目

10.2. 创建UserDao.java接口

package com.lywgames.dao;

public interface UserDao {
	void insert();

	void select();

	void update();

	void delete();
}

10.3. 创建UserDao.java接口的实现类UserDaoImpl.java

package com.lywgames.dao.impl;

import com.lywgames.dao.UserDao;

public class UserDaoImpl implements UserDao {

	@Override
	public void insert() {
		System.out.println("插入User对象。");
	}

	@Override
	public void select() {
		System.out.println("查询User对象。");
	}

	@Override
	public void update() {
		System.out.println("更新User对象。");
	}

	@Override
	public void delete() {
		System.out.println("删除User对象。");
	}

}

10.4. 创建JDKProxy.java代理类

package com.lywgames.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.lywgames.dao.UserDao;

public class JDKProxy implements InvocationHandler{
	private UserDao userDao;
	
	public JDKProxy(UserDao userDao) {
		this.userDao = userDao;
	}
	
	public UserDao createProxy() {
		return (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		if("select".equals(method.getName())) {
			System.out.println("查询User对象前, 对其进行校验。");
			return method.invoke(userDao, args);
		}
		return method.invoke(userDao, args);
	}

}

10.5. 创建Test.java测试类

package com.lywgames;

import com.lywgames.dao.UserDao;
import com.lywgames.dao.impl.UserDaoImpl;
import com.lywgames.proxy.JDKProxy;

public class Test {
	public static void main(String[] args) {
		UserDao userDao = new UserDaoImpl();
		JDKProxy jdkProxy = new JDKProxy(userDao);
		UserDao proxy = jdkProxy.createProxy();
		proxy.insert();
		proxy.select();
		proxy.update();
		proxy.delete();
	}
}

10.6. 运行项目

11. CGLIB动态代理例子

11.1. 新建一个名为CglibProxy的Java项目, 拷入spring-core.java, 她有CGLIB代码

11.2. 创建UserDaoImpl.java类

package com.lywgames.dao.impl;

public class UserDaoImpl {

	public void insert() {
		System.out.println("插入User对象。");
	}

	public void select() {
		System.out.println("查询User对象。");
	}

	public void update() {
		System.out.println("更新User对象。");
	}

	public void delete() {
		System.out.println("删除User对象。");
	}

}

11.3. 创建CglibProxy.java代理类

package com.lywgames.proxy;

import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import com.lywgames.dao.impl.UserDaoImpl;

public class CglibProxy implements MethodInterceptor {
	private UserDaoImpl userDaoImpl;
	
	public CglibProxy(UserDaoImpl userDaoImpl) {
		this.userDaoImpl = userDaoImpl;
	}

	// 使用cglib产生代理
	public UserDaoImpl createProxy() {
		// 创建cglib的核心类
		Enhancer enhancer = new Enhancer();
		// 设置父类
		enhancer.setSuperclass(userDaoImpl.getClass());
		// 设置回调
		enhancer.setCallback(this);
		// 返回增强对象
		return (UserDaoImpl)enhancer.create();
	}
	
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		if("insert".equals(method.getName())) {
			System.out.println("插入User对象前, 对其进行校验。");
			return methodProxy.invokeSuper(proxy, args);
		}
		return methodProxy.invokeSuper(proxy, args);
	}

}

11.4. 创建Test.java测试类

package com.lywgames;

import com.lywgames.dao.impl.UserDaoImpl;
import com.lywgames.proxy.CglibProxy;

public class Test {
	public static void main(String[] args) {
		UserDaoImpl userDaoImpl = new UserDaoImpl();
		CglibProxy cglibProxy = new CglibProxy(userDaoImpl);
		UserDaoImpl proxy = cglibProxy.createProxy();
		proxy.insert();
		proxy.select();
		proxy.update();
		proxy.delete();
	}
}

11.5. 运行项目

12. AOP使用XML配置例子

12.1. 新建一个名为AOPXml的Java项目

12.2. 创建UserDao.java接口

package com.lywgames.dao;

public interface UserDao {
	public void insert();
	public void select();
	public void update();
	public int delete();
}

12.3. 创建UserDao.java接口的实现类UserDaoImpl.java

package com.lywgames.dao.impl;

import com.lywgames.dao.UserDao;

public class UserDaoImpl implements UserDao {

	public void insert() {
		System.out.println("插入数据");
	}

	public void select() {
		System.out.println("查询数据");
	}

	public void update() {
		System.out.println("更新数据");
		throw new RuntimeException();
	}

	public int delete() {
		System.out.println("删除数据");
		return 1;
	}

}

12.4. 创建AspectJAop.java切面类

package com.lywgames.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class AspectJAop {
	public void beforeInsertCheck(JoinPoint jp) {
		System.out.println("检测插入数据, " + jp);
	}
	
	public void afterDelete(int result) {
		System.out.println("删除后返回值: " + result);
	}
	
	public Object arround(ProceedingJoinPoint joinPoint) {
		try {
			System.out.println("查询前鼓鼓掌。");
			Object obj = joinPoint.proceed();
			System.out.println("查询后鼓鼓掌。");
			return obj;
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public void updateException(Throwable ex) {
		System.out.println("更新发生了异常:" + ex.toString());
	}
	
	public void myFinally() {
		System.out.println("更新方法发生了异常, 最终通知一样会执行完成。");
	}
}

12.5. 创建AopAction.java测试类

package com.lywgames.action;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.lywgames.dao.UserDao;

public class AopAction {
	
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao userDao = context.getBean(UserDao.class);
		userDao.insert();
		userDao.delete();
		userDao.select();
		userDao.update();
		context.close();
	}
}

12.6. 在src目录下添加applicationContext.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: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.xsd">

	<bean id="userDao" class="com.lywgames.dao.impl.UserDaoImpl"></bean>
	<bean id="aspectJAop" class="com.lywgames.aop.AspectJAop"></bean>
	
	<!-- 通过aop的配置完成对目标类产生代理 -->
	<aop:config>
		<!-- 表达式配置哪些类的哪些方法需要进行增强 -->
		<aop:pointcut expression="execution(* com..UserDaoImpl.insert(..))" id="pointinsert" />
		<aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.delete(..))" id="pointdelete"/>
		<aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.select(..))" id="pointselect"/>
		<aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.update(..))" id="pointupdate"/> 
		
		<!-- 配置切面 -->
		<aop:aspect ref="aspectJAop"><!-- 引用切面类 -->
			<!-- 前置通知 -->
			<aop:before method="beforeInsertCheck" pointcut-ref="pointinsert" />
			<!-- 后置通知 -->
			<aop:after-returning method="afterDelete" pointcut-ref="pointdelete" returning="result"/>
			<!-- 环绕通知 -->
			<aop:around method="arround" pointcut-ref="pointselect"/>
			<!-- 异常通知 -->
			<aop:after-throwing method="updateException" pointcut-ref="pointupdate" throwing="ex" /> 
			<!-- 最终通知 -->
			<aop:after method="myFinally" pointcut-ref="pointupdate"/>
		</aop:aspect>
	</aop:config>

</beans>

12.7. 运行项目

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值