1、cglib的学习,cglib是靠继承关系来实现代理的目的,即具体代码如下:
- public class AOPInstrumenter implements MethodInterceptor {
- private static Log logger = LogFactory.getLog(AOPInstrumenter.class);
- private Enhancer enhancer = new Enhancer();
- public Object getInstrumentedClass(Class clz) {
- enhancer.setSuperclass(clz);
- enhancer.setCallback(this);
- return enhancer.create();
- }
- public Object intercept(Object o, Method method, Object[] methodParameters,MethodProxy methodProxy) throws Throwable {
- logger.debug("Before Method =>" + method.getName());
- Object result = methodProxy.invokeSuper(o, methodParameters);
- logger.debug("After Method =>" + method.getName());
- return result;
- }
- }
public class AOPInstrumenter implements MethodInterceptor {
private static Log logger = LogFactory.getLog(AOPInstrumenter.class);
private Enhancer enhancer = new Enhancer();
public Object getInstrumentedClass(Class clz) {
enhancer.setSuperclass(clz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] methodParameters,MethodProxy methodProxy) throws Throwable {
logger.debug("Before Method =>" + method.getName());
Object result = methodProxy.invokeSuper(o, methodParameters);
logger.debug("After Method =>" + method.getName());
return result;
}
}
2、proxy代理,主要靠实现接口来实现代理的目的,即具体代码如下:
- public class AOPHandler implements InvocationHandler {
- private static Log logger = LogFactory.getLog(AOPHandler.class);
- private List interceptors = null;
- private Object originalObject;
- /**
- * 返回动态代理实例
- *
- * @param obj
- * @return
- */
- public Object bind(Object obj) {
- this.originalObject = obj;
- return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
- }
- /**
- * 在Invoke方法中,加载对应的Interceptor,并进行
- * 预处理(before)、后处理(after)以及异常处理(exceptionThrow)过程
- */
- public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
- Object result = null;
- Throwable ex = null;
- InvocationInfo invInfo = new InvocationInfo(proxy, method, args,result, ex);
- logger.debug("Invoking Before Intercetpors!");
- invokeInterceptorsBefore(invInfo);
- try {
- logger.debug("Invoking Proxy Method!");
- result = method.invoke(originalObject, args);
- invInfo.setResult(result);
- logger.debug("Invoking After Method!");
- invokeInterceptorsAfter(invInfo);
- } catch (Throwable tr) {
- invInfo.setException(tr);
- logger.debug("Invoking exceptionThrow Method!");
- invokeInterceptorsExceptionThrow(invInfo);
- throw new AOPRuntimeException(tr);
- }
- return result;
- }
- /**
- * 加载Interceptor
- *
- * @return
- */
- private synchronized List getIntercetors() {
- if (null == interceptors) {
- interceptors = new ArrayList();
- //Todo:读取配置,加载Interceptor实例
- interceptors.add(new MyInterceptor());
- }
- return interceptors;
- }
- /**
- * 执行预处理方法
- *
- * @param invInfo
- */
- private void invokeInterceptorsBefore(InvocationInfo invInfo) {
- List interceptors = getIntercetors();
- int len = interceptors.size();
- for (int i = 0; i < len; i++) {
- ((Interceptor) interceptors.get(i)).before(invInfo);
- }
- }
- /**
- * 执行后处理方法
- *
- * @param invInfo
- */
- private void invokeInterceptorsAfter(InvocationInfo invInfo) {
- List interceptors = getIntercetors();
- int len = interceptors.size();
- for (int i = len - 1; i >= 0; i--) {
- ((Interceptor) interceptors.get(i)).after(invInfo);
- }
- }
- /**
- * 执行异常处理方法
- *
- * @param invInfo
- */
- private void invokeInterceptorsExceptionThrow(InvocationInfo invInfo) {
- List interceptors = getIntercetors();
- int len = interceptors.size();
- for (int i = len - 1; i >= 0; i--) {
- ((Interceptor) interceptors.get(i)).exceptionThrow(invInfo);
- }
- }
- }
public class AOPHandler implements InvocationHandler {
private static Log logger = LogFactory.getLog(AOPHandler.class);
private List interceptors = null;
private Object originalObject;
/**
* 返回动态代理实例
*
* @param obj
* @return
*/
public Object bind(Object obj) {
this.originalObject = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
/**
* 在Invoke方法中,加载对应的Interceptor,并进行
* 预处理(before)、后处理(after)以及异常处理(exceptionThrow)过程
*/
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
Object result = null;
Throwable ex = null;
InvocationInfo invInfo = new InvocationInfo(proxy, method, args,result, ex);
logger.debug("Invoking Before Intercetpors!");
invokeInterceptorsBefore(invInfo);
try {
logger.debug("Invoking Proxy Method!");
result = method.invoke(originalObject, args);
invInfo.setResult(result);
logger.debug("Invoking After Method!");
invokeInterceptorsAfter(invInfo);
} catch (Throwable tr) {
invInfo.setException(tr);
logger.debug("Invoking exceptionThrow Method!");
invokeInterceptorsExceptionThrow(invInfo);
throw new AOPRuntimeException(tr);
}
return result;
}
/**
* 加载Interceptor
*
* @return
*/
private synchronized List getIntercetors() {
if (null == interceptors) {
interceptors = new ArrayList();
//Todo:读取配置,加载Interceptor实例
interceptors.add(new MyInterceptor());
}
return interceptors;
}
/**
* 执行预处理方法
*
* @param invInfo
*/
private void invokeInterceptorsBefore(InvocationInfo invInfo) {
List interceptors = getIntercetors();
int len = interceptors.size();
for (int i = 0; i < len; i++) {
((Interceptor) interceptors.get(i)).before(invInfo);
}
}
/**
* 执行后处理方法
*
* @param invInfo
*/
private void invokeInterceptorsAfter(InvocationInfo invInfo) {
List interceptors = getIntercetors();
int len = interceptors.size();
for (int i = len - 1; i >= 0; i--) {
((Interceptor) interceptors.get(i)).after(invInfo);
}
}
/**
* 执行异常处理方法
*
* @param invInfo
*/
private void invokeInterceptorsExceptionThrow(InvocationInfo invInfo) {
List interceptors = getIntercetors();
int len = interceptors.size();
for (int i = len - 1; i >= 0; i--) {
((Interceptor) interceptors.get(i)).exceptionThrow(invInfo);
}
}
}
- public class AOPFactory {
- static AOPHandler txHandler ;
- private static Log logger = LogFactory.getLog(AOPFactory.class);
- /**
- * 根据类名创建类实例
- *
- * @param clzName
- * @return
- * @throws ClassNotFoundException
- */
- public static Object getClassInstance(String clzName) {
- Class cls;
- try {
- cls = Class.forName(clzName);
- return (Object) cls.newInstance();
- } catch (ClassNotFoundException e) {
- logger.debug(e);
- throw new AOPRuntimeException(e);
- } catch (InstantiationException e) {
- logger.debug(e);
- throw new AOPRuntimeException(e);
- } catch (IllegalAccessException e) {
- logger.debug(e);
- throw new AOPRuntimeException(e);
- }
- }
- /**
- * 根据传入的类名,返回AOP代理对象
- *
- * @param clzName
- * @return
- */
- public static Object getAOPProxyedObject(String clzName) {
- txHandler = new AOPHandler();
- Object obj = getClassInstance(clzName);
- return txHandler.bind(obj);
- }
- /**
- * @return Returns the txHandler.
- */
- public static AOPHandler getTxHandler() {
- return txHandler;
- }
- }
public class AOPFactory {
static AOPHandler txHandler ;
private static Log logger = LogFactory.getLog(AOPFactory.class);
/**
* 根据类名创建类实例
*
* @param clzName
* @return
* @throws ClassNotFoundException
*/
public static Object getClassInstance(String clzName) {
Class cls;
try {
cls = Class.forName(clzName);
return (Object) cls.newInstance();
} catch (ClassNotFoundException e) {
logger.debug(e);
throw new AOPRuntimeException(e);
} catch (InstantiationException e) {
logger.debug(e);
throw new AOPRuntimeException(e);
} catch (IllegalAccessException e) {
logger.debug(e);
throw new AOPRuntimeException(e);
}
}
/**
* 根据传入的类名,返回AOP代理对象
*
* @param clzName
* @return
*/
public static Object getAOPProxyedObject(String clzName) {
txHandler = new AOPHandler();
Object obj = getClassInstance(clzName);
return txHandler.bind(obj);
}
/**
* @return Returns the txHandler.
*/
public static AOPHandler getTxHandler() {
return txHandler;
}
}
- public interface Interceptor {
- public void before(InvocationInfo invInfo);
- public void after(InvocationInfo invInfo);
- public void exceptionThrow(InvocationInfo invInfo);
- }
public interface Interceptor {
public void before(InvocationInfo invInfo);
public void after(InvocationInfo invInfo);
public void exceptionThrow(InvocationInfo invInfo);
}
- public class MyInterceptor implements Interceptor {
- private static Log logger = LogFactory.getLog(MyInterceptor.class);
- public void before(InvocationInfo invInfo) {
- logger.debug("Pre-processing");
- }
- public void after(InvocationInfo invInfo) {
- logger.debug("Post-processing");
- }
- public void exceptionThrow(InvocationInfo invInfo) {
- logger.debug("Exception-processing");
- }
- }
public class MyInterceptor implements Interceptor {
private static Log logger = LogFactory.getLog(MyInterceptor.class);
public void before(InvocationInfo invInfo) {
logger.debug("Pre-processing");
}
public void after(InvocationInfo invInfo) {
logger.debug("Post-processing");
}
public void exceptionThrow(InvocationInfo invInfo) {
logger.debug("Exception-processing");
}
}
3、Spring中AOP的实现。剖析Spring中的cglig和proxy。
Spring中的核心模块为:bean和aop;其中bean模块对aop提供了支持。
- public abstract class AbstractBeanFactory implements ConfigurableBeanFactory {
- public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
- String beanName = transformedBeanName(name);
- Object bean = null;
- // Eagerly check singleton cache for manually registered singletons.
- Object sharedInstance = null;
- synchronized (this.singletonCache) {
- sharedInstance = this.singletonCache.get(beanName);
- }
- if (sharedInstance != null) {
- if (sharedInstance == CURRENTLY_IN_CREATION) {
- throw new BeanCurrentlyInCreationException(beanName);
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
- }
- bean = getObjectForSharedInstance(name, sharedInstance); }
- else {
- // Check if bean definition exists in this factory.
- RootBeanDefinition mergedBeanDefinition = null;
- try {
- mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
- }
- catch (NoSuchBeanDefinitionException ex) {
- // Not found -> check parent.
- if (this.parentBeanFactory instanceof AbstractBeanFactory) {
- // Delegation to parent with args only possible for AbstractBeanFactory.
- return ((AbstractBeanFactory) this.parentBeanFactory).getBean(name, requiredType, args);
- }
- else if (this.parentBeanFactory != null && args == null) {
- // No args -> delegate to standard getBean method.
- return this.parentBeanFactory.getBean(name, requiredType);
- }
- throw ex;
- }
- checkMergedBeanDefinition(mergedBeanDefinition, beanName, requiredType, args);
- // Create bean instance.
- if (mergedBeanDefinition.isSingleton()) {
- synchronized (this.singletonCache) {
- // re-check singleton cache within synchronized block
- sharedInstance = this.singletonCache.get(beanName);
- if (sharedInstance == null) {
- if (logger.isInfoEnabled()) {
- logger.info("Creating shared instance of singleton bean '" + beanName + "'");
- }
- this.singletonCache.put(beanName, CURRENTLY_IN_CREATION);
- try {
- sharedInstance = createBean(beanName, mergedBeanDefinition, args);
- this.singletonCache.put(beanName, sharedInstance);
- }
- catch (BeansException ex) {
- this.singletonCache.remove(beanName);
- throw ex;
- }
- }
- }
- bean = getObjectForSharedInstance(name, sharedInstance);
- }
- else {
- // It's a prototype -> create a new instance.
- bean = createBean(name, mergedBeanDefinition, args);
- }
- }
- // Check if required type matches the type of the actual bean instance.
- if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) {
- throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
- }
- return bean;
- }
- }
public abstract class AbstractBeanFactory implements ConfigurableBeanFactory {
public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
String beanName = transformedBeanName(name);
Object bean = null;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = null;
synchronized (this.singletonCache) {
sharedInstance = this.singletonCache.get(beanName);
}
if (sharedInstance != null) {
if (sharedInstance == CURRENTLY_IN_CREATION) {
throw new BeanCurrentlyInCreationException(beanName);
}
if (logger.isDebugEnabled()) {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
bean = getObjectForSharedInstance(name, sharedInstance); }
else {
// Check if bean definition exists in this factory.
RootBeanDefinition mergedBeanDefinition = null;
try {
mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
}
catch (NoSuchBeanDefinitionException ex) {
// Not found -> check parent.
if (this.parentBeanFactory instanceof AbstractBeanFactory) {
// Delegation to parent with args only possible for AbstractBeanFactory.
return ((AbstractBeanFactory) this.parentBeanFactory).getBean(name, requiredType, args);
}
else if (this.parentBeanFactory != null && args == null) {
// No args -> delegate to standard getBean method.
return this.parentBeanFactory.getBean(name, requiredType);
}
throw ex;
}
checkMergedBeanDefinition(mergedBeanDefinition, beanName, requiredType, args);
// Create bean instance.
if (mergedBeanDefinition.isSingleton()) {
synchronized (this.singletonCache) {
// re-check singleton cache within synchronized block
sharedInstance = this.singletonCache.get(beanName);
if (sharedInstance == null) {
if (logger.isInfoEnabled()) {
logger.info("Creating shared instance of singleton bean '" + beanName + "'");
}
this.singletonCache.put(beanName, CURRENTLY_IN_CREATION);
try {
sharedInstance = createBean(beanName, mergedBeanDefinition, args);
this.singletonCache.put(beanName, sharedInstance);
}
catch (BeansException ex) {
this.singletonCache.remove(beanName);
throw ex;
}
}
}
bean = getObjectForSharedInstance(name, sharedInstance);
}
else {
// It's a prototype -> create a new instance.
bean = createBean(name, mergedBeanDefinition, args);
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return bean;
}
}
- public abstract class AbstractBeanFactory implements ConfigurableBeanFactory {
- protected Object getObjectForSharedInstance(String name, Object beanInstance) throws BeansException {
- String beanName = transformedBeanName(name);
- // Don't let calling code try to dereference the
- // bean factory if the bean isn't a factory.
- if (isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
- throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
- }
- // Now we have the bean instance, which may be a normal bean or a FactoryBean.
- // If it's a FactoryBean, we use it to create a bean instance, unless the
- // caller actually wants a reference to the factory.
- if (beanInstance instanceof FactoryBean) {
- if (!isFactoryDereference(name)) {
- // Return bean instance from factory.
- FactoryBean factory = (FactoryBean) beanInstance;
- if (logger.isDebugEnabled()) {
- logger.debug("Bean with name '" + beanName + "' is a factory bean");
- }
- try {
- beanInstance = factory.getObject();
- }
- catch (Exception ex) {
- throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
- }
- if (beanInstance == null) {
- throw new FactoryBeanNotInitializedException(
- beanName, "FactoryBean returned null object: " +
- "probably not fully initialized (maybe due to circular bean reference)");
- }
- }
- else {
- // The user wants the factory itself.
- if (logger.isDebugEnabled()) {
- logger.debug("Calling code asked for FactoryBean instance for name '" + beanName + "'");
- }
- }
- }
- return beanInstance;
- }
- }
public abstract class AbstractBeanFactory implements ConfigurableBeanFactory {
protected Object getObjectForSharedInstance(String name, Object beanInstance) throws BeansException {
String beanName = transformedBeanName(name);
// Don't let calling code try to dereference the
// bean factory if the bean isn't a factory.
if (isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (beanInstance instanceof FactoryBean) {
if (!isFactoryDereference(name)) {
// Return bean instance from factory.
FactoryBean factory = (FactoryBean) beanInstance;
if (logger.isDebugEnabled()) {
logger.debug("Bean with name '" + beanName + "' is a factory bean");
}
try {
beanInstance = factory.getObject();
}
catch (Exception ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
if (beanInstance == null) {
throw new FactoryBeanNotInitializedException(
beanName, "FactoryBean returned null object: " +
"probably not fully initialized (maybe due to circular bean reference)");
}
}
else {
// The user wants the factory itself.
if (logger.isDebugEnabled()) {
logger.debug("Calling code asked for FactoryBean instance for name '" + beanName + "'");
}
}
}
return beanInstance;
}
}
- public class ProxyFactoryBean extends AdvisedSupport
- implements FactoryBean, BeanFactoryAware, AdvisedSupportListener {
- public Object getObject() throws BeansException {
- return this.singleton ? getSingletonInstance() : newPrototypeInstance();
- }
- private Object getSingletonInstance() {
- if (this.singletonInstance == null) {
- super.setFrozen(this.freezeProxy);
- this.singletonInstance = createAopProxy().getProxy();
- }
- return this.singletonInstance;
- }
- }
public class ProxyFactoryBean extends AdvisedSupport
implements FactoryBean, BeanFactoryAware, AdvisedSupportListener {
public Object getObject() throws BeansException {
return this.singleton ? getSingletonInstance() : newPrototypeInstance();
}
private Object getSingletonInstance() {
if (this.singletonInstance == null) {
super.setFrozen(this.freezeProxy);
this.singletonInstance = createAopProxy().getProxy();
}
return this.singletonInstance;
}
}
- final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
- public Object getProxy(ClassLoader classLoader) {
- if (logger.isDebugEnabled()) {
- Class targetClass = this.advised.getTargetSource().getTargetClass();
- logger.debug("Creating JDK dynamic proxy" +
- (targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
- }
- Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
- return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
- }
- }
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
Class targetClass = this.advised.getTargetSource().getTargetClass();
logger.debug("Creating JDK dynamic proxy" +
(targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
}
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}
- public class Cglib2AopProxy implements AopProxy, Serializable {
- public Object getProxy(ClassLoader classLoader) {
- if (logger.isDebugEnabled()) {
- Class targetClass = this.advised.getTargetSource().getTargetClass();
- logger.debug("Creating CGLIB2 proxy" +
- (targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
- }
- Enhancer enhancer = new Enhancer();
- try {
- Class rootClass = this.advised.getTargetSource().getTargetClass();
- if (AopUtils.isCglibProxyClass(rootClass)) {
- enhancer.setSuperclass(rootClass.getSuperclass());
- }
- else {
- enhancer.setSuperclass(rootClass);
- }
- enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised));
- enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
- enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
- Callback[] callbacks = getCallbacks(rootClass);
- enhancer.setCallbacks(callbacks);
- if(CglibUtils.canSkipConstructorInterception()) {
- enhancer.setInterceptDuringConstruction(false);
- }
- Class[] types = new Class[callbacks.length];
- for (int x = 0; x < types.length; x++) {
- types[x] = callbacks[x].getClass();
- }
- enhancer.setCallbackTypes(types);
- // generate the proxy class and create a proxy instance
- Object proxy;
- if (this.constructorArgs != null) {
- proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
- }
- else {
- proxy = enhancer.create();
- }
- return proxy;
- }
- catch (CodeGenerationException ex) {
- throw new AspectException("Couldn't generate CGLIB subclass of class '" +
- this.advised.getTargetSource().getTargetClass() + "': " +
- "Common causes of this problem include using a final class or a non-visible class",
- ex);
- }
- catch (IllegalArgumentException ex) {
- throw new AspectException("Couldn't generate CGLIB subclass of class '" +
- this.advised.getTargetSource().getTargetClass() + "': " +
- "Common causes of this problem include using a final class or a non-visible class",
- ex);
- }
- catch (Exception ex) {
- // TargetSource.getTarget failed
- throw new AspectException("Unexpected AOP exception", ex);
- }
- }
- }