JDK动态代理的原理是根据定义好的规则,用传入的接口创建一个新类,这就是为什么采用动态代理时为什么只能用接口引用指向代理,而不能用传入的类引用执行动态类。
cglib采用的是用创建一个继承实现类的子类,用asm库动态修改子类的代码来实现的,所以可以用传入的类引用执行代理类
Spring AOP
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。Spring主要通过代理来实现AOP。
切面(Aspect):对横切关注点的抽象(类似类对对象的抽象)
连接点(JoinPoint):被拦截到的点,泛指方法。
切入点(CutPoint):对哪些连接点进行拦截的定义。
通知(Advice):在特定的连接点,AOP框架执行的动作.前置/后置/例外/最终/环绕通知。
引入(Introduction): 添加方法或字段到被通知的类。Spring允许引入新的接口到任何被通知的对象。
目标对象(Target Object): 包含连接点的对象。也被称作被通知或被代理对象。
AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
织入(Weaving): 组装切面来创建一个被通知对象。这可以在编译时完成也可以在运行时完成。Spring在运行时完成织入。
示例代码:
接口类:
- package org.iti.wxl.springaop;
- public interface UserService {
- public String getUser(String userId);
- public void addUser();
- }
对接口的实现:
- package org.iti.wxl.springaop;
- public class UserServiceImpl implements UserService {
- @Override
- public String getUser(String userId) {
- System.out.println("this is getUser() method!");
- return "user";
- }
- @Override
- public void addUser() {
- System.out.println("this is addUser() method!");
- }
- }
定义切面:
- package org.iti.wxl.springaop;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.After;
- import org.aspectj.lang.annotation.AfterReturning;
- import org.aspectj.lang.annotation.AfterThrowing;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.aspectj.lang.annotation.Pointcut;
- @Aspect
- public class MyInterceptor {
- @Pointcut("execution(* org.iti.wxl.springaop..*.*(..))")
- private void pointCutmethod(){
- }
- @Before("pointCutmethod() && args(userId)")
- public void doBefore(String userId){
- System.out.println("前置通知 " + userId);
- }
- @AfterReturning("pointCutmethod()")
- public void doAfterReturning(){
- System.out.println("后置通知");
- }
- @AfterThrowing("pointCutmethod()")
- public void doAfterException(){
- System.out.println("异常通知");
- }
- @After("pointCutmethod()")
- public void doAfter(){
- System.out.println("最终通知");
- }
- @Around("pointCutmethod()")
- public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
- System.out.println("环绕开始");
- Object object = pjp.proceed();
- System.out.println("环绕结束");
- return object;
- }
- }
说明:
第一个*表示方法的返回值,这里使用通配符,只有返回值符合条件的才拦截(!void表示有返回值)。
第一个..表示com.royzhou.aop包及其子包。
倒数第二个*表示包下的所有Java类都被拦截。
最后一个*表示类的所有方法都被拦截。
(..)表示方法的参数可以任意多个,如[(java.lang.String,java.lang.Integer)表示第一个参数是String,第二个参数是int的方法才会被拦截]
配置文件:
- <?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-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
- <!-- 使用 annotation -->
- <context:annotation-config />
- <!-- 启用aop -->
- <aop:aspectj-autoproxy proxy-target-class="true" />
- <bean id="myInterceptor" class="org.iti.wxl.springaop.MyInterceptor"/>
- <bean id="userService" class="org.iti.wxl.springaop.UserServiceImpl"/>
- </beans>
测试类:
- package org.iti.wxl.springaop;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class SpringAOP {
- public static void main(String[] args) {
- ApplicationContext cxt = new ClassPathXmlApplicationContext("bean.xml");
- UserService userService = (UserService)cxt.getBean("userService");
- userService.getUser("user1");
- System.out.println("===========");
- userService.addUser();
- }
- }
运行结果:
- 前置通知 user1
- 环绕开始
- this is getUser() method!
- 后置通知
- 最终通知
- 环绕结束
- ===========
- 环绕开始
- this is addUser() method!
- 后置通知
- 最终通知
- 环绕结束
在项目开发中,AOP主要用来配置spring的声明式事务管理,它还可用在日志管理,性能监测等。它为程序员编程提供了一种新思路,我们可以不断去发现它的新用途。
相关推荐
### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...
在Java编程领域,动态代理和Cglib代理是两种常用的技术,用于在运行时创建对象的代理,以实现额外的功能,如AOP(面向切面编程)中的日志、事务管理等。本篇文章将深入探讨这两种代理机制,尤其是Cglib代理。 首先...
Java 实现免费代理IP的获取方式 并动态实时校验是否有效,java文件项目内含有Jsoup的Jar包(Jsoup是加工过的,含请求),有2个主入口程序: 其一:用于请求代理IP,并立即校验是否是一个有效的代理IP,如果有效,...
Java代理机制是Java编程中一个重要的特性,它允许我们在不修改原有代码的基础上,为已有类增加额外的功能。本文将深入探讨两种主要的Java代理实现:JDK动态代理和CGLIB代理。 一、JDK动态代理 JDK动态代理基于接口...
### Java动态代理实现AOP详解 #### 一、引言 随着软件开发复杂度的提升,传统的面向对象编程(OOP)已经难以满足现代软件工程的需求。为了更好地管理跨切面的关注点,如日志记录、性能监控、安全控制等,面向切面...
在深入探讨Java动态代理的实现过程之前,我们首先需要理解动态代理的基本概念及其在Java中的应用价值。动态代理,顾名思义,是在运行时动态创建代理对象的一种机制,它无需在编译期就确定代理类的具体实现,而是通过...
java动态代理 public class HireProxy implements InvocationHandler { //被代理的真实角色 private Object obj; public HireProxy(Object obj) { super(); this.obj = obj; } //第二个参数method,被...
二、静态代理 静态代理是在编译时就确定的,代理类的代码是显式编写的。在给定的例子中,`HelloServiceProxy` 是一个静态代理类,它持有一个 `HelloService` 的引用,即 `HelloServiceImpl` 对象。当客户端调用 `...
#### 二、Java动态代理机制 Java动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。`Proxy`类提供了一个静态方法`newProxyInstance()`用于创建动态代理对象,而`...
Java代理模式是一种设计模式,它在面向对象编程中扮演着重要的角色,主要目的是为了在不修改原有对象的基础上,为对象添加额外的功能或者控制对对象的访问。代理模式的核心思想是通过代理类来间接调用目标类的方法,...
#### 二、Java动态代理的基本原理 Java动态代理的核心是`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。下面详细介绍这两个核心组成部分: 1. **`Proxy`类**:提供了一系列静态方法...
### Java设计模式之虚拟代理模式详解 #### 一、引言 在软件工程领域,设计模式作为一种被广泛接受的最佳实践,对于提高代码质量和可维护性起着至关重要的作用。其中,“代理模式”作为结构型设计模式之一,在解决...
二是JDK的动态代理API,如java.lang.reflect.Proxy类。动态代理更加灵活,不需要为每个目标类单独编写代理类。 3. **远程代理:**远程代理是代理模式的一个特殊应用,它使得客户端可以像操作本地对象一样操作远程...
Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理) Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解...
#### 二、Java动态代理原理 Java动态代理的核心类主要有两个:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。 1. **Proxy**:这是一个工具类,用于创建一个实现了一组给定接口的动态代理...
在Java中,有两种主要的动态代理实现方式:一是使用`java.lang.reflect.Proxy`类,二是使用`java.lang.invoke.MethodHandles`和`java.lang.invoke.MethodHandle`。这里我们主要讨论`Proxy`类。 首先,让我们理解...
### Java代理技术详解:JDK代理、CGLIB与AspectJ #### 一、代理模式简介 代理模式是一种常见的设计模式,在《Design Patterns in Java》一书中对其有明确的定义:“代理模式为一个对象提供一个代理,以控制对该...