`
JerryWang_SAP
  • 浏览: 1030583 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

面向切片编程(AOP)应用的一些实际例子

阅读更多

The definition of AOP in wikipedia seems a little bit difficult for beginners to understand, so in this blog I use an example to introduce why we need it.

Suppose I have an order command class which performs its core business logic in method doBusiness:

package aop;
import java.util.logging.Level;
import com.sun.istack.internal.logging.Logger;
public class OrderCommand {
 public void execute(){
  Logger logger = Logger.getLogger(OrderCommand.class);
  logger.log(Level.INFO, "start processing");
  // authorization check
  logger.log(Level.INFO, "authorization check");
  logger.log(Level.INFO, "begin performance trace");
  // only this line implements real business logic
  this.doBusiness();
  logger.log(Level.INFO, "end performance trace");
 }
 private void doBusiness(){
  System.out.println("Do business here");
 }
 public static void main(String[] args) {
  new OrderCommand().execute();
 }
}

In method execute(), it is flooded with too many non-functional code like logging, authorization check and performance trace.

 

 

It is not a good design, we can try to improve it via template method pattern.

Template method pattern

With this pattern, I create a new parent class BaseCommand, and put all non-functional code inside the execute method.

import java.util.logging.Level;
import com.sun.istack.internal.logging.Logger;
public abstract class BaseCommand {
public void execute(){
  Logger logger = Logger.getLogger(this.getClass());
  logger.log(Level.INFO, "start processing");
  // authorization check
  logger.log(Level.INFO, "authorization check");
  logger.log(Level.INFO, "begin performance trace");
  // only this line implements real business logic
  this.doBusiness();
  logger.log(Level.INFO, "end performance trace");
}
protected abstract void doBusiness();
}

Now the real business logic is defined in child class OrderCommand, whose implementation is very clean:

public class OrderCommand extends BaseCommand {
public static void main(String[] args) {
  new OrderCommand().execute();
}
@Override
protected void doBusiness() {
    System.out.println("Do business here");
}
}

Drawback of this solution: as the parent class has defined the template method execution, it is NOT possible for a child class to adapt it, for example, a child class cannot change the order sequence of authorization check and performance trace method. And suppose a child class does not want to implement authorization check at all – this could not be achieved with this solution. We have to use decorator pattern instead.

Decorator pattern

First I need to create an interface:

public interface Command {
public void execute();
}

And create a decorator to cover the log and authorization check function:

import java.util.logging.Level;
import com.sun.istack.internal.logging.Logger;
public class LoggerDecorator implements Command{
private Command cmd;
public LoggerDecorator(Command cmd){
  this.cmd = cmd;
}
@Override
public void execute() {
  Logger logger = Logger.getLogger(this.getClass());
  logger.log(Level.INFO, "start processing");
  // authorization check
  logger.log(Level.INFO, "authorization check");
  this.cmd.execute();
}
}

And a second decorator for performance trace:

package aop;
import java.util.logging.Level;
import com.sun.istack.internal.logging.Logger;
public class PerformanceTraceDecorator implements Command{
private Command cmd;
public PerformanceTraceDecorator(Command cmd){
  this.cmd = cmd;
}
@Override
public void execute() {
  Logger logger = Logger.getLogger(this.getClass());
  logger.log(Level.INFO, "begin performance trace");
  this.cmd.execute();
  logger.log(Level.INFO, "end performance trace");
}
}

And the class to finish the real business logic. Now I have the full flexibility to constructor the instance according to real business case, with the help of different decorator. The following instance fullCmd owns the ability of both authorization check log and performance trace.

public class OrderCommand implements Command {
public static void main(String[] args) {
  Command fullCmd = new LoggerDecorator( new PerformanceTraceDecorator( new OrderCommand()));
  cmd.execute();
}
@Override
public void execute() {
  System.out.println("Do business here");
}
}

Suppose in a given scenario, only performance trace is needed, we can just use the performance trace decorator:

Command cmd = new PerformanceTraceDecorator( new OrderCommand());
cmd.execute();

Drawback of decorator pattern: The decorator class and the business class have to implement the same interface, command, which is more business related. Is there possibility that the utility classes for non-functional implementation can just work without implementing the same interface which is implemented by business class?

AOP solution

I use a Java project implemented by Spring framework to demonstrate the idea.

Suppose I hope to add performance trace on this business method: save.

 

 

(1) You may have already observed the annotation @Log(nameI042416=”annotation for save method”) used in line10. This annotation is declared in file Log.java:

 

 

(2) Now I have to declare an Aspect class which contains a pointcut. A pointcut tells Spring framework which methods could be applied with AOP strategy, and the class annotated with @Aspect contains methods which should be called by Spring framework to “decorate” the methods identified by annotation. Here below I have declared a pointcut “logJerry” via annotation @Pointcut:

 

 

For example, since we have annotated the business method save() with “@Log(nameI042416=”annotation for save method”)”, we can define what logics must be done on it, with the help of @Before and @After plus declared pointcut.

 

 

With this approach, I can add performance trace function to save method without modifying its source code.

Set breakpoint on these beforeExec and afterExec methods, launch the project with Tomcat under debug mode, paste the following url to your browser: http://localhost:9498/springaop/aopRootJerry/aop2Jerry/i042416?string=sap Through callstack you can understand how the AOP call is working in Spring.

 

 

Why we say AOP can increase modularity by allowing the separation of cross-cutting concerns?

Suppose we have lots of methods all of which need common utilities like log, performance trace and authorization check. Before we use AOP, these utilities are scattered in every method:

 

 

After AOP is used, those common stuff are extracted into Aspect class and reusability is fulfilled. From the picture below we can see the cross-cutting concerns are now separated.

 

 

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

0
1
分享到:
评论

相关推荐

    SpringAop面向切片

    **Spring AOP 面向切面编程详解** 在Java世界中,Spring框架以其强大的功能和易用性闻名,其中一个核心特性就是面向切面编程(Aspect-Oriented Programming,简称AOP)。AOP是为了解决传统面向对象编程中横切关注点...

    AopSample:面向切片AOP示例

    面向切片AOP(Aspect-Oriented Programming)是一种编程范式,它旨在提高代码的可重用性和模块化,主要用于解决传统OOP中横切关注点的问题。在Java中,AOP通常通过Spring框架实现,它允许开发者定义“切面”,这些切...

    利用SPring AOP配置切面的一个例子

    面向切面编程是一种编程范式,它旨在通过将横切关注点(Cross-cutting Concerns)从业务逻辑中分离出来,提高代码的可读性和可维护性。横切关注点是指那些遍布于应用各处的、与核心业务逻辑无关的功能,如日志记录、...

    spring-aop和注解的实例

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。这些关注点通常与业务逻辑无关,但又在多个地方被用到,AOP就是为了...

    spring切面小例子

    在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点从核心业务逻辑中分离出来,例如日志记录、事务管理、性能监控等。本示例将深入探讨如何在Spring中实现AOP,特别是通过注解的方式。...

    面向切面所需jar包

    面向切面编程(AOP)是一种编程范式,它旨在将关注点分离,使得系统中的核心业务逻辑与横切关注点(如日志、事务管理、权限检查等)解耦。在Java领域,AspectJ是一个广泛应用的AOP框架,它提供了强大的编译时和运行...

    基于切面的日志记录SSMdemo

    Spring为应用提供了全面的控制反转(IoC)和面向切面编程(AOP)支持;SpringMVC作为Spring的一部分,负责处理HTTP请求;MyBatis则简化了数据库操作,通过XML或注解的方式将SQL与Java代码绑定。 在SSM项目中,日志...

    注解小例子

    Spring框架利用注解来声明依赖注入、AOP(面向切面编程)、事务管理等核心功能。 1. **依赖注入(DI)注解**:Spring的核心特性之一是依赖注入,它通过注解实现组件之间的解耦。例如,`@Autowired`注解用于自动装配...

    google-api-services-pagespeedonline-v1-rev43-1.17.0-rc.zip

    AOP(面向切面编程)是一种编程范式,它允许在不修改源代码的情况下,对程序进行横向切片,如日志记录、事务管理等。在这个例子中,"aop-logging"提供了一种声明性注解的方式来进行日志记录,这意味着开发者可以在...

    spring框架学习源代码

    Spring框架是Java开发中最常用的轻量级框架之一,它以其依赖注入(Dependency Injection,简称DI)和面向切面编程(Aspect-Oriented Programming,简称AOP)的核心特性,极大地简化了企业级应用的开发工作。...

Global site tag (gtag.js) - Google Analytics