目录
Spring AOP面向切面编程(spring动态代理注解版)
静态代理
列:实现静态代理
代理接口User.java
public interface User {
/*
* 业务接口
* */
public void work(String workName);
public void doing(); //增加接口
}
目标对象 实际业务逻辑实现方法UserImpl.java
public class UserImpl implements User{
@Override
public void work(String workName) {
// TODO Auto-generated method stub
System.out.println("老王 "+ ".");
}
@Override
public void doing() {
// TODO Auto-generated method stub
}
}
代理类UserProxy.java
实现业务逻辑接口,接收一个实际业务处理对象
public class UserProxy implements User{
private User user;
public UserProxy(User user) {
super();
this.user = user;
}
@Override
public void work(String workName) {
// TODO Auto-generated method stub
check();
user.work(workName);
printLog();
}
@Override
public void doing() {
}
private void printLog() {
// TODO Auto-generated method stub
System.out.println("权限验证");
}
private void check() {
// TODO Auto-generated method stub
System.out.println("打印日志");
}
}
测试
@org.junit.Test
public void test1() {
User userProxy = new UserProxy(new UserImpl());
userProxy.work("在吃饭");
}
动态代理
列: 实现动态代理
创建po对象
创建dao
创建user接口与 接口实现类
创建角色接口与 接口实现类
创建代理类 MyProxy.java
//3创建代理对象
public class MyProxy implements InvocationHandler{
private Object object;//3.1生命委托对象
//3.2 有参数的构造方法
public MyProxy(Object object) {
super();
this.object = object;
}
//3.3得到代理对象
public Object getProxyObjectInstance() {
//Proxy.newProxyInstance(类加载器,接口,代理对象的实例)
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}
//3.4生成代理对象
/**
* 在代理实例上处理方法调用并返回结果
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
check();
Object retObject=method.invoke(object, args);
printLog();
return retObject;
}
public void check(){
System.out.println("用户权限验证");
}
public void printLog(){
System.out.println("打印日志");
}
}
测试
/**
* 测试user代理对象
*/
@org.junit.Test
public void testUserProxyObject() {
MyProxy myProxy=new MyProxy(new UserDaoImpl());//委托
UserDao userDao=(UserDao)myProxy.getProxyObjectInstance();//获取代理对象
userDao.addUser(new User());
System.out.println();
String id=userDao.getId();
System.out.println("id==="+id);
}
/**
* 测试role代理对象
*/
@org.junit.Test
public void testRoleProxuObject() {
MyProxy myProxy=new MyProxy(new RoleDaoImpl());
RoleDao roleDao=(RoleDao)myProxy.getProxyObjectInstance();//获取role代理对象
int a=roleDao.deleteRole(1);
System.out.println(a);
}
Spring Aop 面向切面编程(spring动态代理)
Aop 采用横向抽取机制,底层采用JDK动态代理.
- JointPoint 连接点: 所谓连接点是指哪些被拦截到的点,在spring中,这些点指的就是方法,因为spring只支持方法类型的连接点.
详解:通知指业务接口中的方法均为连接点…UserDaoImpl中的方法
- pointCut 切入点: 所谓切入点是指我们对哪些JoinPoint进行拦截的定义.
详解:我们对哪些Joinpoint进行拦截的定义,addUser().
- Advice(通知/增强): 拦截到JointPoint之后所要做的事情就是通知,
通知有5种。为分前置通知,后置通知,异常通知,最终通知,环绕通知。 详解:拦截的目标对象的addUser()方法,时机(之前/之后等) 执行,通知切面完成功能.
- Target 目标对象 :代理的目标对象. UserDaoImpl.
- 切面aspect :泛指业务逻辑根据动态代理的例子. check(),printLog()可以理解为切面.
列:aop练习
导包
User.java
public class User {
private String id;
private String name;
public User() {
// TODO Auto-generated constructor stub
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + "]";
}
}
UserDao.java
/**
* 代理接口(目标对象实现的接口)
*
*/
public interface UserDao {
public void save();
public void update();
public void query();
public void delete(int id);
}
public class UserDaoImpl implements UserDao {
/*
* save()是切入点
*/
public void save() {
// TODO Auto-generated method stub
System.out.println("执行save..");
}
public void update() {
// TODO Auto-generated method stub
System.out.println("执行update..");
}
public void query() {
// TODO Auto-generated method stub
System.out.println("执行query.. 发成异常");
int rs=100/0;
}
public void delete(int id) {
// TODO Auto-generated method stub
System.out.println("执行delete");
}
}
MyAspect.java切面
public class MyAspect {
/**
* 切面
*/
public void check(){
System.out.println("切面---检查权限 ---前置通知");
}
public void writeLog(){
System.out.println("写入日志---后置通知");
}
//ProceedingJoinPoint 连接点
public Object aroud(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("前");
System.out.println("连接点方法参数:"+joinPoint.getArgs());//连接点方法参数
//joinPoint.getArgs().length参数长度
for(int i=0;i<joinPoint.getArgs().length;i++){
System.out.println("连接点参数值:"+joinPoint.getArgs()[i]);
}
System.out.println(joinPoint.getTarget());//
Object ret=joinPoint.proceed();//执行连接点
System.out.println("ret=="+ret);
System.out.println("后");
return ret;
}
public void afterThrowing(Throwable ex){
System.out.println("异常通知"+ex);
}
public void after(){
System.out.println("最终通知֪");
}
}
bean.xml实现
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1实例化目标对象 -->
<!-- 配置目标对象 -->
<bean id="userDao" class="com.iotek.user.dao.UserDaoImpl"></bean>
<!-- 2实例化切面:将切面交给spring容器管理 -->
<bean id="myAspect" class="com.iotek.user.dao.MyAspect"></bean>
<!-- 3 命名空间: xmlns:aop="http://www.springframework.org/schema/aop"
约束: http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd -->
<!-- 4 书写代理对象:通过aop的配置完成对目标类产生代理 -->
<aop:config>
<!--5 写切入点pointCut expression:切面表达式 -->
<aop:pointcut expression="execution(* com.iotek.user.dao.UserDaoImpl.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* com.iotek.user.dao.UserDaoImpl.update(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* com.iotek.user.dao.UserDaoImpl.delete(..))" id="pointcut3"/>
<aop:pointcut expression="execution(* com.iotek.user.dao.UserDaoImpl.query(..))" id="pointcut4"/>
<!--6 写切面aspect pointcut-ref:引用切入点名称 -->
<aop:aspect ref="myAspect">
<!-- 7通知advice:前置通知 -->
<aop:before method="check" pointcut-ref="pointcut1"/>
<!-- 8后置通知 -->
<aop:after-returning method="writeLog" pointcut-ref="pointcut2"/>
<!-- 9环绕通知 -->
<aop:around method="aroud" pointcut-ref="pointcut3"/>
<!-- 10异常通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
<!-- 11最终通知 (不管有无异常都会执行) -->
<aop:after method="after" pointcut-ref="pointcut4"/>
</aop:aspect>
</aop:config>
</beans>
测试
public class SpringTest {
/**
* 前置通知测试
*/
@Test
public void test1(){
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao=(UserDao)context.getBean("userDao");
userDao.save();
userDao.update();
}
/**
* 后置通知测试
*/
@Test
public void test2(){
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao=(UserDao)context.getBean("userDao");
userDao.update();
}
/**
* 环绕通知测试
*/
@Test
public void test3(){
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao=(UserDao)context.getBean("userDao");
userDao.delete(100);
}
/**
* 异常通知
*/
@Test
public void test4(){
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao=(UserDao)context.getBean("userDao");
userDao.query();
}
}
结果:
Spring AOP面向切面编程(spring动态代理注解版)
列:spring动态代理注解版
导包
User.java
UserDao.java
public interface UserDao {
public void save();
public void delete();
public void update();
public void query();
}
UserDaoImpl.java
@Component(value="userDaoImpl")//注解版实例化
public class UserDaoImpl implements UserDao{
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("UserDaoImpl save");
}
@Override
public void delete() {
// TODO Auto-generated method stub
System.out.println("UserDaoImpl delete");
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("UserDaoImpl update");
}
@Override
public void query() {
// TODO Auto-generated method stub
//int a=1/0;
System.out.println("UserDaoImpl query");
}
}
beans.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:p="http://www.springframework.org/schema/p"
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--1注解装配 xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" -->
<!-- 扫描包下的所有的类 -->
<context:component-scan base-package="com.lws"></context:component-scan>
<!-- 2添加aop命名空间 xmlns:aop="http://www.springframework.org/schema/aop"
引用aop约束http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd -->
<!-- 3开启注解版aop配置(启用aspectj对象Annotation支持) -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
MyAspect.java
@Component//实例化切面
@Aspect
public class MyAspect {
//配置切入点方法
@Pointcut("execution( * com.lws.dao.UserDaoImpl.*(..))")
public void myAspectMetod() {
System.out.println("我是切入点");
}
//1前置通知
@Before(value="myAspectMetod()")
public void check(){
System.out.println("权限验证");
}
//2后置通知
@After(value="myAspectMetod()")
public void printLog(){
System.out.println("写入日志文件");
}
//3环绕通知
@Around(value="myAspectMetod()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
// System.out.println("前");
check();
Object obj=joinPoint.proceed(); //执行方法
printLog();
// System.out.println("后");
return obj;
}
//4异常通知
@AfterThrowing(value="myAspectMetod()",throwing="ex")
public void afterThrowing(Throwable ex){
System.out.println("异常抛出通知"+ex);
}
//5最终通知一定会被执行的通知
@AfterReturning(value="myAspectMetod()", returning="object")
public void afterReturning(Object object){
System.out.println("最终通知"+object);
}
}
Test.java
public class Test {
private ClassPathXmlApplicationContext context;
@Before
public void init() {
context=new ClassPathXmlApplicationContext("beans.xml");
}
/**
* 8前置通知
*/
@org.junit.Test
public void beforeTest() {
UserDao ud=(UserDao)context.getBean("userDaoImpl");
ud.save();
System.out.println(ud);
}
/**
* 8.2后置通知
*/
@org.junit.Test
public void afterTest() {
UserDao ud=(UserDao)context.getBean("userDaoImpl");
ud.update();
System.out.println(ud);
}
/**
* 8.3环绕通知
*/
@org.junit.Test
public void aroundTest() {
UserDao ud=(UserDao)context.getBean("userDaoImpl");
ud.delete();
System.out.println(ud);
}
/**
* 8.4异常通知
*/
@org.junit.Test
public void exTest() {
UserDao ud=(UserDao)context.getBean("userDaoImpl");
ud.query();
System.out.println(ud);
}
/**
* 8.5一定会被执行的
*/
@org.junit.Test
public void uTest() {
UserDao ud=(UserDao)context.getBean("userDaoImpl");
ud.query();
System.out.println(ud);
}
}
来源:CSDN
作者:birdlun
链接:https://blog.csdn.net/Birdmotianlun/article/details/102546202