JAVA AOP

AOP背景

 

Dijkstra--separation of concerns(分散关注)

所谓的分离关注就是将某一通用的需求功能从不相关的类之中分离出来;同时,能够使得很多类共享一个行为,一旦行为发生变化,不必修改很多类,只要修改这个行为就可以。

设计模式孜孜不倦追求的是调用者和被调用者之间的解耦。

OOP-面向对象编程

针对问题领域中以及业务处理过程中存在的实体及其属性和操作进行抽象和封装。

面向对象的核心概念是纵向结构的,其目的是获得更加清晰高效的逻辑单元划分。

 

 

AOP:Aspect oriented programming. AOP实际是设计模式的一种扩展,提供从另一个角度来考虑程序结构以完善面向对象编程(OOP)。

面向对象将应用程序分解成各个层次的对象。

而AOP将程序分解成各个方面或者说关注点这使得可以模块化诸如事务管理等这些横切多个对象的关注点。(这些关注点术语称作横切关注点。)

AOP的核心思想就是将应用程序中的业务逻辑处理部分同对其提供支持的通用服务,即所谓的“横切关注点”进行分离,这些“横切关注点”贯穿了程序中的多个纵向模块的需求。

事务

安全

日志……

 

 

 

AOP是一个概念,并没有设定具体语言的实现,它能克服那些只有单继承特性语言的缺点(如Java),目前AOP具体实现有以下几个项目:

AspectJ (TM):创建于Xerox PARC. 有近十年历史,成熟。缺点:过于复杂;破坏封装;需要专门的Java编译器。

动态AOP:使用JDK的动态代理API或字节码Bytecode处理技术。

 

 

AOP目的


 



 

应用切面


 

 

基于JAVA动态代理的AOP实现原理

 

 

public class AOPHandler implements InvocationHandler {
	private List interceptors = null;
	private Object objOriginal;
	
	public Object bind(Object objOriginal) {
		this.objOriginal = objOriginal;
                //返回动态代理实例
		return Proxy.newProxyInstance(objOriginal.getClass().getClassLoader(), objOriginal.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;
		Throwable ex = null;
		InvocationInfo invInfo = new InvocationInfo(proxy, method, args, objOriginal, ex);
                //预执行
		invokeInterceptorsBefore(invInfo);	
		try {
			result = method.invoke(objOriginal, args);
			invInfo.setResult(result);
                        //后执行
			invokeInterceptorsAfter(invInfo);
		} catch (Exception e) {
			invInfo.setException(e);
                        //异常执行
			invokeInterceptorsException(invInfo);
		}
		return result;
	}
	//加载Interceptor
	private synchronized List getInterceptors() {
		if(interceptors == null) {
			interceptors = new ArrayList();
			Properties p = new Properties();
			ClassLoader loader = AOPHandler.class.getClassLoader();
			try {
				p.load(loader.getResourceAsStream("interceptor.properties"));
				String interceptorName = p.getProperty("interceptorName");
				Class cl = Class.forName(interceptorName);
				interceptors.add(cl.getConstructor(new Class[]{}).newInstance(new Object[]{}));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return interceptors;
	}

	private void invokeInterceptorsBefore(InvocationInfo invInfo) {
		interceptors = getInterceptors();
		int len = interceptors.size();
		for(int i=0; i<len; i++) {
			((MyInterceptor) interceptors.get(i)).before(invInfo);
		}
	}
	
	private void invokeInterceptorsAfter(InvocationInfo invInfo) {
		interceptors = getInterceptors();
		int len = interceptors.size();
		for(int i=0; i<len; i++) {
			((MyInterceptor) interceptors.get(i)).after(invInfo);
		}
	}
	
	private void invokeInterceptorsException(InvocationInfo invInfo) {
		interceptors = getInterceptors();
		int len = interceptors.size();
		for(int i=0; i<len; i++) {
			((MyInterceptor) interceptors.get(i)).exceptionThrow(invInfo);
		}
	}
}

 

 

 

interceptor.properties配置文件:

InterceptorName=com.ht.MyInterceptor

 

 

拦截信息基本类

 

public class InvocationInfo {
	private Object proxy;
	private Method method;
	private Object[] args;
	private Object result;
	private Throwable exception;
	
	public InvocationInfo(Object proxy, Method method, Object[] args, Object result, Throwable exception) {
		this.proxy = proxy;
		this.method = method;
		this.args = args;
		this.result = result;
		this.exception = exception;
	}
	
	public Object getProxy() {
		return proxy;
	}
	public void setProxy(Object proxy) {
		this.proxy = proxy;
	}
	public Method getMethod() {
		return method;
	}
	public void setMethod(Method method) {
		this.method = method;
	}
	public Object[] getArgs() {
		return args;
	}
	public void setArgs(Object[] args) {
		this.args = args;
	}
	public Object getResult() {
		return result;
	}
	public void setResult(Object result) {
		this.result = result;
	}
	public Throwable getException() {
		return exception;
	}
	public void setException(Throwable exception) {
		this.exception = exception;
	}
}

 

 

自定义拦截器接口

public interface Interceptor {
	public void before(InvocationInfo invInfo);
	public void after(InvocationInfo invInfo);
	public void exceptionThrow(InvocationInfo invInfo);
}

 

具体拦截器实现

public class MyInterceptor implements Interceptor {

	@Override
	public void before(InvocationInfo invInfo) {
		System.out.println("pre processing...");
	}

	@Override
	public void after(InvocationInfo invInfo) {
		System.out.println("post processing...");
	}

	@Override
	public void exceptionThrow(InvocationInfo invInfo) {
		System.out.println("exception processing...");
	}
}

 

AOP 工厂类建立

public class AOPFactory {
	public static Object getProxyInstance(String clName) {
		AOPHandler handler = new AOPHandler();
		Class c;
		Object proxy = null;
		try {
			c = Class.forName(clName);
			proxy = handler.bind(c.newInstance());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return proxy;
	}
}

执行

HelloWorld proxy = (HelloWorld) AOPFactory.getProxyInstance("com.ht.HelloWorldImpl");
proxy.sayHello();

 

注:实例proxy与HelloWorldImpl 均实现了统一的HelloWorld接口定义方法,通过建立代理可以方便地将日志,安全等事务进行委托。

 

### Java AOP (Aspect-Oriented Programming) Implementation and Usage In software engineering, Aspect-Oriented Programming (AOP) complements Object-Oriented Programming by facilitating the modularization of cross-cutting concerns such as logging, transaction management, security checks, etc., which span multiple classes or methods. In the context of Java applications, especially those built on top of frameworks like Spring, AOP plays an essential role in enhancing code maintainability and separation of concerns. #### Understanding Cross-Cutting Concerns Cross-cutting concerns refer to functionalities that affect more than one point of an application but do not fit well into any specific business logic component because they cut across various parts of the system. Traditional object-oriented programming languages struggle with encapsulating these concerns effectively without causing tight coupling between unrelated components[^2]. #### Implementing AOP Using Spring Framework The Spring framework supports two primary approaches for implementing AOP: - **Proxy-Based Approach**: Utilizes dynamic proxies or CGLIB libraries depending upon whether interfaces exist for advised objects. This approach works at runtime and is simpler to configure; however, it has limitations when dealing with constructor interceptions or private/protected members. - **AspectJ Weaving Approach**: Offers greater flexibility compared to proxy-based solutions since this technique allows intercepting method executions along with constructors inside target classes. However, using AspectJ requires understanding its weaving mechanism prior to adoption due to differences in operational modes[^1]. For developers preferring ease-of-use alongside powerful features offered out-of-the-box, Spring Boot simplifies configuring aspects via annotations while adhering closely to established conventions regarding singleton scopes unless explicitly overridden. Below demonstrates how simple it becomes under Spring Boot environment leveraging `@Aspect` annotation together with other utility annotations provided specifically for defining advice around join points. ```java import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logMethodCall() { System.out.println("Logging Method Call"); } } ``` This example defines a basic aspect named `LoggingAspect`, where every time a service layer method from package `com.example.service` gets invoked, console output will display "Logging Method Call". Such implementations help decouple core functionality from supporting utilities ensuring cleaner architecture design principles throughout projects utilizing Java platforms.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值