写代码应该是一个由繁到简,然后由简到繁的一个螺旋上升的过程。
在Spring中有个很重要的特性那就是面向切面编程(AOP)。假想这样的一个情景,如果有一段逻辑很多方法执行前或执行后都需要,我们会怎么办?我们试着从一个极端走到另一个极端来考虑这个问题。从一个极端出发,如果需要这段逻辑的方法个数很少只有一个,我们可以直接在方面的最前面或最后面调用这段逻辑,怎么简单怎么来,像这样:
public void function(){ commonBegin(); ... commonEnd(); }
当这样的方法从一个变成两三个的时候,我们就看到了两三个类似的方法,然后当方法数变得特别多的时候,我们就会看到一堆这样的方法,当不只有一个Begin或End,而是还包含其他的Begin和End时,随着代码的不断增多,代码看起来估计就像套马杆的汉子般威武雄壮了...
那怎样才能把这样的问题搞的简单点呢?找代理~
1、静态代理:
首先我们可以尝试一下找个静态代理,静态代理就是谁是谁的代理都已经很明显了,一对一的服务,像这个样子(举个例子,你的一序列的方法都属于一些顾客的行为):
public class Proxy implements Cliemt{ private Client client; //Client只是其中的一个顾客类 public Proxy(Client client){ this.client = client; } public void buy(){ doSomething(); client.buy(); //顾客的工作就是买买买 } }
这样的话,顾客方法里面就不需要写那些前置或者后置的逻辑,代理里面来实现这部分就可以了,保证了顾客清清白白,然而,然而,这样不就凭空多了跟顾客类一样多的代理类了吗,代码不仅没有减少,反而翻番了。
2、JDK动态代理:
静态代理不行,那就找动态代理。动态代理会根据你的类生产对应的代理类,首先看看JDK的动态代理的实现机制。在静态代理中,有多少类需要实现同一个共同逻辑就需要对应多少个静态代理类,如果代理类中的代理对象类型没有指定的话,即前面没有指定ClientImpl,那么可以抽象出一个代理的调用控制器,在控制器中通过反射机制来调用具体对象的方法:
public class DynamicInvocationHandler implements InvocationHandler{ private Object object; public DynamicInvocationHandler (Object object){ this.object = object; } public Object invoke(Object proxy, Method method, Object... params){ return method.invoke(object, params); // try } }
然后我们可以通过Java中的Proxy根据我们的调用控制器来动态生成我们的代理:
Client client= new ClientImpl(); DynamicInvocationHandler handler = new DynamicInvocationHandler (client); Client clientProxy = (Client ) Proxy.newInstance(client.getClass().getClassLoader(), client .getClass().getInterfaces(), handler);
3、CGLIB动态代理:
JDK动态代理需要类实现相应的接口,如果是针对没有接口的类,可以使用CGlib来实现,实现方式大概是这个样子:
public class CGLibInterceptor implements MethodInterceptor{ public Object intercept(Object object, Method method, Object... params, MethodProxy proxy){ return proxy.invokeSuper(object, params); // try } }
然后可以通过Enhance的create方法创建代理对象:
CGLibInterceptor cglibInterceptor = new CGLibInterceptor(); Hello helloProxy = (Hello)Enhancer.create(Hello.class, cglibInterceptor); helloProxy.say("````");
有了动态代理之后,当我们对某个类的方法前或之后调用特定的逻辑时,就可以创建一个动态的代理对象出来,特定的逻辑放在InvocationHandler或MethodInterceptor中,可以把这两个类看成是动态代理的中介,有了这个中介之后,不管什么类都可以根据需要创建出对应的动态代理,省去了编写一堆静态代理的麻烦,而这个中介中的特定逻辑其实就是AOP的中切面(待续~)
相关推荐
在Spring部分,书中会详细讲解Spring框架的核心组件,如依赖注入(DI)、面向切面编程(AOP)和Spring MVC。依赖注入是Spring的核心特性,它使得对象之间的关系在运行时动态绑定,提高了代码的可测试性和可维护性。...
7. **AOP(面向切面编程)**:面向切面编程允许我们在不修改原有代码的情况下,添加新的功能或进行日志记录、性能监控等操作。Smart框架可能通过实现AspectJ或Spring AOP来实现这一特性。 8. **国际化与本地化**:...
4. **AOP(面向切面编程)**:学习如何使用切面编程来实现跨切面的关注点,比如日志记录、事务管理等,使得代码更加模块化。 5. **持久层技术**:书中可能会涉及数据库操作,如JDBC、MyBatis或Hibernate,这些都是...
8. **AOP(面向切面编程)**:AOP允许我们定义横切关注点,如日志记录、事务管理等,使其与业务代码解耦。我们将探讨如何在框架中实现AOP机制。 9. **会话管理**:为了保持用户状态,Web应用常常需要使用会话。我们...
6. ** IOC与AOP**:控制反转(IOC)和面向切面编程(AOP)是Spring框架的核心特性。通过IOC容器,可以实现依赖注入,简化对象之间的依赖关系;AOP则用于分离关注点,如日志记录、权限控制等。书中会详细讲解这两个...
6. **Spring框架**:Spring是Java企业级应用的事实标准,提供了依赖注入、AOP(面向切面编程)、事务管理、数据访问和Web MVC框架。深入理解Spring Boot和Spring Cloud还能帮助开发者快速构建微服务架构。 7. **...
10. **AOP(面向切面编程)**:利用AOP实现日志记录、事务管理等功能,使得代码更加模块化,提高可维护性。 11. **数据库集成**:介绍JDBC基础,以及ORM(对象关系映射)框架如Hibernate或MyBatis,简化数据库操作...
Spring框架以其依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)为核心,简化了Java应用的开发。在书中,作者首先会介绍Spring的基本理念和框架结构,包括IoC容器和Bean的...
6. **AOP(面向切面编程)**:JavaWeb框架中,AOP常用于日志记录、权限控制等横切关注点。书中会讲解AOP的概念和实现,以及如何在自定义框架中实现类似功能。 7. **持久层技术**:对于数据存储,书中可能涉及数据库...
6. **Spring框架基础**:虽然标题强调从零开始,但了解Spring框架的基本概念和工作原理,如依赖注入(DI)和面向切面编程(AOP),将有助于理解JavaWeb框架的设计思想。 7. **数据库连接与JDBC**:JavaWeb框架通常...
1. Spring框架:除了Spring MVC,Spring还提供了依赖注入、AOP(面向切面编程)、数据访问/集成、任务调度等多种功能,是构建企业级应用的基石。 2. Hibernate和MyBatis:持久层框架如Hibernate和MyBatis简化了...
拦截器通常用于AOP(面向切面编程),如权限检查、日志记录等;过滤器则常用于数据的转换、编码、安全过滤等。 6. **依赖注入**: 为了实现代码的松耦合,依赖注入(DI)是一种常用的设计模式。Spring框架的IoC...
- AOP(面向切面编程):允许开发者定义横切关注点,如性能监控、日志记录、异常处理等。 - 数据校验:提供数据验证机制,确保输入的有效性。 - i18n(国际化):支持多语言环境,便于应用的全球化。 - IOC...
5. **AOP(面向切面编程)**:学习如何使用切面来组织代码,提高代码的可维护性和可重用性。 6. **持久层框架**:如Hibernate或MyBatis,用于数据库操作,理解ORM(对象关系映射)的概念。 接下来,我们转向《从...
Spring提供了依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)架构等核心功能,有助于简化开发流程并提高代码的可测试性。你还将学习如何配置和使用Spring Boot,这是一个快速开发工具,可以简化Spring应用...