`
greemranqq
  • 浏览: 975756 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Spring AOP 学习(一) 代理模式

阅读更多

Spring 为解耦而诞生,其中AOP(面向切面编程)是很浓重的一笔。

这里简单记录一下AOP 给我带来的好处:

1.

用了一段时间,想通过简单的代码,更好的阐述以及理解它。

 

以前:假设我们有个简单的业务,还是经典的Hello World,那么我们定义一个Service 接口,一个ServiceImpl 实现类,一个sayHello 方法,这里使用网上很经典的日志记录的例子。

 

1.Service接口:定义一个sayHello  的业务方法

public interface Service {
	public void sayHello();
}

 

2.ServiceImpl实现类:主要是打印HelloWord,但是日常项目中,在主要业务前后可能会添加日志记录,或者开启事务等其他必要操作。

public class ServiceImpl implements Service{

	@Override
	public void sayHello() {
		System.out.println("前置日记:打印、启动事务等..");
		System.out.println("Hello world!");
		System.out.println("后置日记:打印、关闭事务等..");
	}
}

 

例子很简单,那么假设,我们不光拥有sayHello ,还有sayBye 等多个方法,并且都需要其他操作呢?那么你是不是会写很多个这样的,重复的代码?

当然,你可以减少一部分工作量,你可以这样:

public class ServiceImpl implements Service{

	@Override
	public void sayHello() {
		before();
		System.out.println("Hello world!");
		after();
	}

	@Override
	public void sayBye() {
		before();
		System.out.println("Bye bye!");
		after();
	}
	
	public static void before(){
		System.out.println("前置日记:打印、启动事务等..");
	}
	
	public static void after(){
		System.out.println("后置日记:打印、关闭事务等..");
	}
}

 

我们再次假设,如果我们拥有更多的业务方法:sayHi(),sayOther()....,需要更多的其他操作:打印信息,传输记录....。并且其他ServiceImpl 里面的方法也需要这些方法呢?那么我们是不是每个类又要继续添加呢?

当然,你可以这样做:建立一个对Service 添加额外功能的类,统一提供。

public class ServiceFactory {
	public static void before(){
		System.out.println("前置日记:打印、启动事务等..");
	}
	
	public static void after(){
		System.out.println("后置日记:打印、关闭事务等..");
	}
	
	public static void other(){
		System.out.println("做其他的事..");
	}
}

 

ServiceImpl 就成这样:

public class ServiceImpl implements Service{

	@Override
	public void sayHello() {
		ServiceFactory.before();
		System.out.println("Hello world!");
		ServiceFactory.after();
	}

	@Override
	public void sayBye() {
		ServiceFactory.before();
		System.out.println("Bye bye!");
		ServiceFactory.after();
	}

	@Override
	public void sayHi() {
		ServiceFactory.before();
		System.out.println("Hi");
		ServiceFactory.after();
		
		ServiceFactory.other();
	}
}

 

 这样代码,感觉是少了一些,但是我们的原则是尽量 别重复同样的代码,提高代码的复用性,改动最小为基准。也许业务很复杂,比较多,那么你要重复多少代码,整个类要写得多麻烦所啊!如果到时候有些假设before 和after 需要变化位置,你又要改动多少呢?

 

当然,目前的的JDK (大于1.3)为了解决这些问题,为我们提供的反射机制,动态代理机制。看看如何更好的解决这个问题。这里先copy 下,什么是代理:

 

Java的动态代理机制
代理模式是常用的Java设计模式。代理类主要负责为委托类预处理消息、过滤信息、把消息转发给委托类,以及事后处理信息等。
    理论 - -总是那么抽象(~。~),简单点说,就是:1.我的目的是去学校,那么校服 早餐 校车,这些我都需要,但是不由我做,全部代理给我父母搞定了(当然我是自己搞定的。)2.再简单的说就是:我只关注我主要的事情,其他附加的事情,全部交给别人搞定。看代码..

MyPorxy 我的代理类:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class MyProxy implements InvocationHandler{
	
	// 目标对象,也就是我们主要的业务,主要目的要做什么事
	private Object delegate;
	
	/**
	 * 和你额外需要做得事情,进行绑定,返回一个全新的对象(写法,基本上固定的)
	 * @param delegate
	 * @return
	 */
	public Object bind(Object delegate){
		this.delegate = delegate;
		return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(), 
				this.delegate.getClass().getInterfaces(), this);
	}
	
	/**
	 * 你刚才需要执行的方法,都需要通过该方法进行动态调用
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object obj = null;
		// 执行前置的方法
		ServiceFactory.before();
		// 通过反射,执行目标方法,也就是你的主要目的
		obj = method.invoke(this.delegate, args);
		// 执行后置的方法
		ServiceFactory.after();
		// 返回值给调用者
		return obj;
	}

}

 

这里运用的反射知识,还需要去看看,这里就不解释了。

 

ServiceImpl 变化:

public class ServiceImpl implements Service{

	@Override
	public void sayHello() {
		System.out.println("Hello world!");
	}

	@Override
	public void sayBye() {
		System.out.println("Bye bye!");
	}

	@Override
	public void sayHi() {
		System.out.println("Hi");
	}
}

 

   测试类:

 

public class Test {

	/**
	 * 测试类
	 * @param args
	 */
	public static void main(String[] args) {
		// 不启用代理
		//Service service = new ServiceImpl();
		// 使用代理
		Service service = (Service)new MyProxy().bind(new ServiceImpl());
		
		service.sayHello();
		service.sayBye();
		service.sayHi();
	}
}

 

 

OK,那么你现在看看,我们的业务实现类ServiceImpl 是不是干净多了,代码是不是在某些地方见过呢?即时你再进行添加更多的方法,也可以同样实现了对吗?当然,在Test里面,假设我们有的方法想用,有的方法不想用,那么又该怎么实现呢?

 

分享到:
评论

相关推荐

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    这种通过代理模式实现的AOP方法,可以很好地将业务逻辑代码与额外的横切关注点分离,使得代码更加清晰,易于维护。如果将来需要去除日志记录功能,只需要替换掉代理类的实例,而不需要修改任何业务逻辑代码。此外,...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态代理。 JDK 动态代理是基于接口的,它要求被代理的目标对象必须实现至少一个接口。Spring 使用 `java.lang.reflect.Proxy`...

    spring之AOP(动态代理)

    在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点分离,将横切关注点(如日志、事务管理、权限检查等)与核心业务逻辑解耦。AOP的核心概念是切面、通知、连接点、切入点和织入。在...

    spring aop 学习笔记

    - Spring AOP的实现涉及到反射、动态代理、代理模式等多个核心Java技术。 - `org.springframework.aop.framework.ProxyFactoryBean` 和 `org.springframework.aop.framework.JdkDynamicAopProxy` 是动态代理的关键...

    springAop默认代理方式.zip

    Spring AOP会为每个目标对象创建一个子类,并覆盖其方法,添加AOP代理逻辑。 4. **代理模式的创建**:Spring AOP 使用`org.springframework.aop.framework.ProxyFactoryBean`或`@EnableAspectJAutoProxy`注解来配置...

    第四章:Spring AOP API 设计模式1

    10. **代理模式(Proxy)**:Spring AOP的核心就是代理模式,它创建了目标对象的代理,代理对象在调用实际目标方法之前/之后执行额外的逻辑(如日志、事务管理等),提供了对对象行为的扩展。 11. **模板方法模式...

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -

    本文将深入探讨Spring AOP的实现原理,以及如何使用反射来实现动态代理模式。 首先,我们需要了解AOP的基本概念。AOP的核心思想是切面,它包含两个主要部分:切点(Pointcut)和通知(Advice)。切点定义了在程序...

    SpringAOP之探秘(动态代理、责任链模式、注解使用)

    学习这些示例,你可以更深入地理解Spring AOP的工作原理,掌握如何使用动态代理和责任链模式来编写切面,以及如何通过注解简化AOP的配置和使用。这些知识对于任何涉及Spring框架的开发者来说都是至关重要的,因为...

    Spring AOP学习资料(pdf)

    通过本资料的学习,我们了解到Spring AOP是一种强大的工具,它通过代理机制有效地分离了业务逻辑与系统需求,极大地提升了系统的可维护性和扩展性。掌握Spring AOP的基本概念和实现方法对于开发高效、健壮的企业级...

    SpringAop学习笔记以及实现Demo

    1. **经典代理模式**:通过JDK动态代理或CGLIB,Spring可以创建一个代理对象来拦截目标对象的方法调用,并在调用前后执行相应的通知。 2. **基于注解的AOP**: - 定义切面类,使用`@Aspect`注解标记。 - 使用`@...

    springAOP之代理模式.docx

    【Spring AOP与代理模式】 Spring AOP,即Spring中的面向切面编程,是一种用于解决传统面向对象编程(OOP)中代码冗余问题的技术。在OOP中,常见的如日志记录、权限验证等功能往往需要在每个业务方法中重复编写,...

    Spring_AOP_学习小结 Spring_AOP_学习小结 Spring_AOP_学习小结

    三、Spring AOP代理原理 Spring AOP通过两种代理机制实现: 1. JDK动态代理:只能代理实现了接口的目标对象,性能相对较低,需要指定代理接口。 2. CGLIB代理:可代理接口和非final的类,性能较高,通过生成字节...

    代理模式与动态代理--Spring AOP原理.doc

    代理模式与动态代理--Spring AOP原理.doc

    spring aop 五个依赖jar

    在Java应用中,AOP通过代理模式实现了切面编程,使得我们可以将业务逻辑与横切关注点分离,提高代码的可复用性和可维护性。 在描述中提到的"spring aop 五个依赖jar"是实现Spring AOP功能必不可少的库文件,让我们...

    spring aop的demo

    在`springAop1`这个压缩包中,可能包含了一个简单的应用示例,展示了如何定义一个切面类,以及如何在该类中定义通知方法。例如,我们可能会看到一个名为`LoggingAspect`的类,其中包含了`@Before`注解的方法,用于在...

    springAop的配置实现

    - **代理(Proxy)**:Spring AOP通过代理模式来实现切面功能,有JDK动态代理和CGLIB代理两种方式。 **2. JDK 动态代理** - 当目标类实现了接口时,Spring AOP会选择使用JDK动态代理。它会生成一个实现了目标类所有...

    spring AOP依赖三个jar包

    - **代理模式**:Spring AOP支持JDK动态代理和CGLIB代理,根据目标对象是否实现了接口来选择合适的代理方式。 - **自动代理生成**:Spring容器可以在启动时自动识别并生成代理对象,无需手动创建。 - **事务管理**...

    小马哥讲 Spring AOP 编程思想 - API 线索图.pdf

    4. AOP代理对象的来源和类型 - **TargetSource(目标源)**:被代理对象的来源。 - **SingletonTargetSource**:总是返回同一个实例的TargetSource。 - **PrototypeTargetSource**:返回原型bean的TargetSource。...

    Spring-AOP-JDK动态代理

    Spring AOP通过代理模式实现了这一概念,允许开发者在不修改源代码的情况下插入额外的功能。 JDK动态代理是Java提供的一种创建代理对象的方式,它在运行时根据接口生成一个实现了这些接口的代理类。Spring AOP可以...

    spring AOP 引入jar包,spring IOC 引入Jar包

    5. **代理(Proxy)**:Spring AOP 使用动态代理技术创建对象,有两种代理方式:JDK 动态代理和 CGLIB 代理。前者适用于接口实现类,后者适用于没有接口的类。 6. **注解使用**:如 @Aspect、@Before、@After、@...

Global site tag (gtag.js) - Google Analytics