Spring中AOP编程的本质是:无须修改源码增加系统功能。所谓的系统功能即为AOP中的A,方面,体现在代码上称为Advice(增强):即日志、审核、权限、计时等每个系统均可能要使用到的功能。在感受AOP让我们见证神奇的背后,我们可以通过以下方式不同程度地实现:
1. JavaSE 动态代理;
从JDK1.3开始,便加入了可协助动态生成代理类的API。在这些API中,一个主要接口是
java.lang.reflect.InvocationHandler以及import java.lang.reflect.Proxy。在动态代理中,我们主要编写该接口的实现类型。
2. 动态字节码生成;
针对指定的类动态生成一个子类,并且覆盖其中的方法,从而增加系统功能。其中最流行的工具是:
CGLIB(Code Generation Library).
缺点:无法为 final 方法或类 提供代码。
3. Java代码生成;
生成新的Java源码,在其中提供横切性的代码,例如EJB的代码生成策略;
由于动态代理和动态字节码生成技术的出现,这种做法正在逐渐退出使用;
4. 使用定制的类加载器;
自定义类加载器,在一个类被加载时自动对其进行横切入系统功能,改变new操作符的行为。
JBoss和AspectWerkz采用这种做法。
缺点:偏离Java标准,在某些应用服务器中可能出现问题,因为J2EE服务器需要控制整个类加载的层级体系。
5. 语言扩展;
增加Java语言功能,使其在OOP编程基础上从语言级别上支持AOP。这一点类似于C++扩展C,引入OO概念一样。
AspectJ就对Java进行了扩展。
缺点:复杂,且引用新的语言。
OOP编程中一些模式也已经解决了AOP希望解决的部分问题:
. Decorator(装饰器模式): 类似于静态代理;
. CORBA在处理远程调用时提供了拦截器的概念;
. Servlet2.3规范引入的servlet拦截器会在处理Web请求的前后被调用;
这些解决方案的主要问题是:它们将拦截器的代码与特定的API或上下文环境(例如:处理远程调用)绑在一起,不够通用。
Spring中AOP构建在动态代码和字节码生成概念基础上, 提供更优雅、更通用的解决方案。Spring中将要增加的系统功能体现为Advice接口的实现类型。根据系统功能加入目标对象的时刻又分为:
1. 前增强(before,pre):在连接点调用之前,首先调用增强;
2. 后增强(after,post):在连接点调用之后,首先调用增强;
a. 返回后增强(after returning advice):在调用成功(没抛异常)之后;
b. 抛出增强(throws advice):在抛出某种特定类型的异常之后;
c. 后增强(after advice):在连接点调用后,不管是否抛异常;
3. 环绕增强(around):完全控制流程,除完成本身工作,还要负责主动调用连接点;
不同增强授受的参数不同;例如后增强获得实际方法的返回值,但抛出增强则不能;
我们应从可用性角度出发,尽量使用功能最弱,目的最明确的增强,这样可以使程序更加清晰。
Spring中为了对系统功能加入到目标对象的方法进行进一步精细控制,提供PointCut接口。然后将系统功能结合到目标对象的工作交由配置文件完成。Advice编写是简单的,PointCut接口的实现类是现成的,配置的代码是可以参考的,但配置文件中一个名为ProxyFactoryBean的工作原理是很重要的。为了能近距离感受AOP神奇背后的普通,我们可以自行编写ProxyFactoryBean。在看具体的源码之前,对ProxyFactory所实现的接口稍做说明:
1. BeanFactoryAware: 实现该接口的Bean对象在由Spring框架实例化完后,会由Spring框架自动注入BeanFactory对象;
2. FactoryBean: 实现该接口,通过该Bean对象所配置的Bean的名称获得的不是该Bean对象,而是该Bean对象方法getObject()返回的对象;
3. InvocationHandler: 实现该接口,动态地改变所执行原方法的功能,实现在原方法前、后或前后加入增强;
原码如下:
package common;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.FactoryBean;
public class MyProxyFactoryBean implements
BeanFactoryAware, FactoryBean, InvocationHandler{
private Object target;
private Class[] proxyInterfaces;
private List interceptorNames=new ArrayList();
private List realInterceptorNames=null;
private BeanFactory factory;
@Override
public Object getObject() throws Exception {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
proxyInterfaces,
this
);
}
@Override
public Class getObjectType() {
return target.getClass();
}
@Override
public boolean isSingleton() {
return true;
}
public void setTarget(Object target) {
this.target=target;
}
public void setProxyInterfaces(String proxyInterfaces) {
try {
this.proxyInterfaces=new Class[]{Class.forName(proxyInterfaces)};
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
@Override
public Object invoke(Object proxy,
Method method, Object[] args)
throws Throwable {
if(realInterceptorNames==null) {
realInterceptorNames=new ArrayList();
for(Object o: interceptorNames) {
realInterceptorNames.add(factory.getBean(o.toString()));
}
}
for(Object o: realInterceptorNames) {
if(o instanceof MethodBeforeAdvice)
((MethodBeforeAdvice)o).before(method, args, target);
}
Object result=method.invoke(target,args);
return result;
}
public void setInterceptorNames(
List interceptorNames) {
this.interceptorNames=interceptorNames;
}
@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
this.factory=arg0;
}
}
分享到:
相关推荐
总的来说,这个压缩文件"spring aop用到jar包.rar"包含了实现Spring AOP所需的一系列核心库,它们共同构成了Spring AOP的基础架构,使得我们可以方便地编写和应用切面,提高代码的可维护性和可扩展性。在实际项目中...
- `org.springframework.aop.framework.ProxyFactoryBean` 和 `org.springframework.aop.framework.JdkDynamicAopProxy` 是动态代理的关键类。 - `org.springframework.aop.aspectj.AspectJExpressionPointcut` ...
深入研究Spring AOP的源码,可以帮助我们更好地理解其工作原理,例如,可以查看`org.springframework.aop.framework.ProxyFactoryBean`、`org.springframework.aop.aspectj.autoproxy.AspectJProxyFactoryBean`、`...
Spring AOP提供了一种优雅的方式,使开发者能够更加专注于业务逻辑的编写,同时确保诸如事务管理、日志记录等功能的统一管理和实现。通过上面的介绍和示例,我们可以看到Spring AOP的强大之处,以及它是如何简化开发...
在阅读源码时,我们可以深入了解Spring AOP的代理实现,例如`Advised`接口和`AopProxy`接口,以及`DefaultAdvisorAdapterRegistry`、`ProxyFactoryBean`等类的作用。理解这些内部机制有助于我们更好地利用Spring AOP...
压缩包中的文件 "spring aop源代码分析.doc" 可能包含了对Spring AOP源代码的详细解读,分析了其关键类和方法,比如`org.springframework.aop.framework.ProxyFactoryBean`、`org.springframework.aop.aspectj....
<bean id="transactionalService" class="org.springframework.aop.framework.ProxyFactoryBean"> *">PROPAGATION_REQUIRED, -java.lang.Exception ``` 这里,`realService`是我们的业务服务对象,`...
**Spring AOP介绍** ...学习并掌握Spring AOP及其源码分析对于提升作为IT专业人员的技术水平至关重要,它不仅能够帮助我们编写更加优雅和简洁的代码,还能使我们更好地应对复杂的企业级应用需求。
3. **学习并实践基于代理的AOP实现**:通过本实验,学生将了解如何利用Spring提供的代理机制(如JDK动态代理、CGLIB代理、ProxyFactoryBean等)来实现AOP功能。 #### 三、实验设计与实现 ##### 1. 定义`MyClass`类...
Spring AOP的实现主要涉及到`org.springframework.aop.framework.ProxyFactoryBean`、`org.springframework.aop.framework.DefaultAopProxyFactory`、`org.springframework.aop.aspectj.AspectJExpressionPointcut`...
- **ProxyFactoryBean**:Spring AOP中的代理工厂Bean,用于创建代理对象。 #### 六、实战示例:模拟Warcraft游戏 - **示例简介**:通过一个模拟游戏的例子来演示如何使用Spring AOP来处理游戏中的横切关注点。 - *...
在Spring框架中,面向切面编程(Aspect-Oriented Programming,简称AOP)是一种强大的工具,它允许开发者定义“横切关注点”,这些关注点通常涉及日志、事务管理、安全性等,可以独立于业务逻辑进行编写。Spring AOP...
这种方式允许开发者在 Spring 的配置文件中直接声明 AOP 的切面、切入点以及通知等元素,而无需编写复杂的 Java 代码。 - **切面声明**:使用 `<aop:aspect>` 元素来定义一个切面。 - **切入点声明**:使用 `<aop:...
在Spring中,AOP的核心类包括:AspectJExpressionPointcut、AdvisedSupport、ProxyFactoryBean等。AspectJExpressionPointcut负责解析并匹配切点表达式,AdvisedSupport则管理着通知、目标类、代理类型等信息,而...
- **Spring AOP**:作为Spring框架的核心组件之一,Spring AOP使用纯Java实现,并遵循AOP联盟定义的标准接口。 2. **Spring AOP的特点**: - **非强制依赖**:Spring IoC容器(包括BeanFactory和...
在AOP部分,`org.springframework.aop.framework.ProxyFactoryBean`用于创建代理对象,实现切面功能。 Spring框架还支持注解驱动开发,如`@Autowired`用于自动装配依赖,`@Service`、`@Repository`和`@Controller`...
Spring框架是Java开发中最广泛应用的轻量级框架之一,它以IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)为核心,极大地简化了企业级应用的开发工作。这份"spring 源码...
`org.springframework.aop`包下包含了AOP的核心实现,如`Advised`接口和`ProxyFactoryBean`类。 二、数据访问支持 1. **JDBC抽象层**:Spring提供了对JDBC的简化封装,通过`JdbcTemplate`和`SimpleJdbcTemplate`,...