Spring框架中动态代理与AOP的学习

6 篇文章 0 订阅
3 篇文章 0 订阅

一,动态代理

 概念:动态代理是一种非常重要的技术,它允许在运行时动态地创建代理对象,以便于在代理对象中添加一些额外的功能。动态代理可以分为两种:JDK动态代理和CGLIB动态代理。JDK动态代理是基于Java反射机制实现的,只能代理接口类型的类;而CGLIB动态代理则是基于字节码技术实现的,可以代理普通的类。

示例:

假设我们有一个接口UserService和一个实现类UserServiceImpl,现在我们需要在每次调用UserService的方法时记录日志。我们可以通过动态代理来实现这个功能。

1,首先,我们需要定义一个代理类UserServiceProxy,并实现InvocationHandler接口

public class UserServiceProxy implements InvocationHandler { 
private Object target; 
public UserServiceProxy(Object target)
 { this.target = target; }
 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 System.out.println("调用方法:" + method.getName());
 Object result = method.invoke(target, args);
 System.out.println("方法调用结束"); return result;
 }
 }

2,然后,在UserService接口中添加一个方法getProxy(),用于创建代理对象

public interface UserService { 
    void addUser(String name);
     void deleteUser(String name);
     Object getProxy(); 
}

3,在UserServiceImpl实现类中,实现getProxy()方法,创建代理对象

public class UserServiceImpl implements UserService {
 @Override
     public void addUser(String name) { 
        System.out.println("添加用户:" + name); 
    }
@Override public void deleteUser(String name) { 
    System.out.println("删除用户:" + name);
 }
 @Override public Object getProxy() {
     return Proxy.newProxyInstance(UserServiceImpl.class.getClassLoader(),                     UserServiceImpl.class.getInterfaces(), new UserServiceProxy(this)); 
    } 
}

4,最后,在测试代码中,调用getProxy()方法来获取代理对象,然后调用addUser()deleteUser()方法

public class Test {
public static void main(String[] args) {
         UserService userService = new UserServiceImpl().getProxy();
         userService.addUser("张三");
         userService.deleteUser("张三");
     }
 }

可以看到,每次调用UserService接口的方法时,都会先输出方法名称,然后调用实际的方法,最后输出方法调用结束的信息。

二,AOP

概念:在Spring框架中,AOP是一个重要的功能模块,它提供了一种方便的方式来实现横切关注点的处理。Spring AOP基于代理模式实现,通过动态代理技术,可以在不修改原有代码的情况下,将横切关注点与核心业务逻辑进行分离。

Spring AOP中的概念:

  1. 切面(Aspect):横切关注点的实现,是一个类,其中包含了通知和切点。

  2. 通知(Advice):切面中的具体逻辑实现,如前置通知、后置通知、环绕通知等。

  3. 切点(Pointcut):定义了哪些类、方法需要被切入,通常使用表达式进行定义。

  4. 连接点(Joinpoint):程序执行过程中的一个点,如方法调用、异常处理等。

  5. 织入(Weaving):将切面应用到目标对象上的过程。

示例:

1,创建一个BookService接口

package com.smrsar.service;

public interface BookService {

    void findAll();

    int add();

    void del(int id);

    void update();
}

2,创建BookService的实现类

package com.smrsar.service.impl;

import com.smrsar.service.BookService;

public class BookServiceImpl implements BookService {
    @Override
    public void findAll() {
        System.out.println("全查");
    }

    @Override
    public int add() {
        System.out.println("添加");
        return 0;
    }

    @Override
    public void del(int id) {
        System.out.println("删除");
    }

    @Override
    public void update() {
        System.out.println("修改");
    }
}

3,创建通知/增强类

package com.smrsar.log;

public class Loggs {

    public void before(){
        System.out.println("前置通知/增强:权限验证");
    }

    public void afterReturning(){
        System.out.println("后置通知/增强:日志输出");
    }

    public void afterThrowing(){
        System.out.println("异常通知/增强:异常处理");
    }
    public void after(){
        System.out.println("最终通知/增强:资源释放");
    }
}

4,创建spring.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:context="http://www.springframework.org/schema/context"
       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/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--1.把所有类的对象交给IOC容器进行管理-->
    <bean id="loggs" class="com.smrsar.log.Loggs"/>
    <bean id="bookService" class="com.smrsar.service.impl.BookServiceImpl"/>
    <!--2.AOP的配置:让增强类 的 哪个方法  动态进行何种增强   核心类 的 哪个方法-->
    <aop:config>
        <aop:aspect id="check" ref="loggs">
            <aop:before method="before" pointcut="execution(* *..BookServiceImpl.*(..))"/>
            <aop:after-returning method="afterReturning" pointcut="execution(* *..BookServiceImpl.*(..))"/>
            <aop:after-throwing method="afterThrowing" pointcut="execution(* *..BookServiceImpl.*(..))"/>
            <aop:after method="after" pointcut="execution(* *..BookServiceImpl.*(..))"/>
        </aop:aspect>
    </aop:config>
</beans>

5,测试

package com.smrsar.servlet;

import com.smrsar.service.BookService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test01 {

    public static void main(String[] args) {
         ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
        BookService bookService = context.getBean(BookService.class);
        bookService.findAll();

    }
}

6,输出结果


前置通知/增强:权限验证
全查
后置通知/增强:日志输出
最终通知/增强:资源释放

 总结:Spring框架中的AOP功能就是基于动态代理实现的,通过使用切面、通知、切点等概念,来实现对目标对象的增强。AOP用于实现在不修改原有代码的情况下,增强程序的功能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值