Spring Aop主要是通过AbstractAutoProxyCreator实现的BeanPostProcessor、InstantiationAwareBeanPostProcessor以及SmartInstantiationAwareBeanPostProcessor接口里面的后置处理器方法,来介入到Spring IOC容器的Bean的实例化以及初始化的过程中对Bean进行AOP的处理的。
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean {
/**
* 这里决定了如果目标类没有实现接口直接就是Cglib代理
* 检查给定beanClass上的接口们,并交给proxyFactory处理
*/
protected void evaluateProxyInterfaces(Class> beanClass, ProxyFactory proxyFactory) {
// 找到该类实现的所有接口们
Class>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
// 标记:是否有存在合理的接口
boolean hasReasonableProxyInterface = false;
for (Class> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
//不管接口是否合理,都将其添加进去
for (Class> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
proxyFactory.setProxyTargetClass(true);
}
}
}
buildAdvisors(beanName, specificInterceptors)
对横切逻辑实例进行包装
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
// 解析interceptorNames而来得Advisor数组
Advisor[] commonInterceptors = resolveInterceptorNames();
List
resolveInterceptorNames
解析interceptorNames而来得Advisor数组
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
private Advisor[] resolveInterceptorNames() {
BeanFactory bf = this.beanFactory;
ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
List advisors = new ArrayList<>();
for (String beanName : this.interceptorNames) {
if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
Object next = bf.getBean(beanName);
advisors.add(this.advisorAdapterRegistry.wrap(next));
}
}
return advisors.toArray(new Advisor[0]);
}
}
wrap
this.advisorAdapterRegistry.wrap(next)
将满足不是正在创建中的横切逻辑实例,给统一转换成Advisor
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果已经是Advisor,则无需多做处理
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
//必须是Advice类型
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
//如果是MethodInterceptor,则直接使用DefaultPointcutAdvisor进行包装
return new DefaultPointcutAdvisor(advice);
}
// 否则遍历注册的适配器,如果存在支持的适配器则使用 DefaultPointcutAdvisor 进行包装
//BeforeAdvice、AfterAdvice、ThrowsAdvice三种通知类型的支持是借助适配器模式来实现的
//AdvisorAdapterRegistry,DefaultAdvisorAdapterRegistry和GlobalAdvisorAdapterRegistry
//主要负责对AdvisorAdapter进行注册
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
}
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}
}
class ObjenesisCglibAopProxy extends CglibAopProxy {
public ObjenesisCglibAopProxy(AdvisedSupport config) {
super(config);
}
}
class CglibAopProxy implements AopProxy, Serializable {
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
this.advisedDispatcher = new AdvisedDispatcher(this.advised);
}
}
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
//若是equals方法不需要代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
//若是hashCode方法不需要代理
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
// 如果当前方法是Spring织入的DecoratingProxy接口中的方法,则返回目标对象的Class类型
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
//如果被代理的对象本身就实现了Advised接口,则证明该类里面的方法已经被代理了,直接执行即可
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//是否将动态代理暴露给AopContext
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
//获取我们的目标对象
target = targetSource.getTarget();
Class> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
//把aop的advisor转化为拦截器链
List
getInterceptorsAndDynamicInterceptionAdvice
List
把aop的advisor转化为拦截器链
public class AdvisedSupport extends ProxyConfig implements Advised {
/**
* 将之前注入到advisorChain中的advisors转换为MethodInterceptor
* 和InterceptorAndDynamicMethodMatcher集合
*/
public List
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 注意这里是递归调用,所以是从索引为-1的拦截器开始调用,并按序递增
//如果拦截器链中的拦截器调用完毕,就执行被代理的方法本身
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//执行目标方法
return invokeJoinpoint();
}
//获取第一个方法拦截器使用的是前++,获取下一个要执行的拦截器
//每递归调用一次,currentInterceptorIndex加一。
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
//精确匹配
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
//递归调用
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
// 匹配错误,跳过,调用下一个
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 如果拦截的不是精确到方法级别的,比如是拦截一整个类,就直接调用,不用再匹配方法了
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
}
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
@Nullable
protected Object invokeJoinpoint() throws Throwable {
// 反射执行连接点,也就是原方法,target为被代理的对象实例、method为执行的方法、arguments为方法参数
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
}
public abstract class AopUtils {
@Nullable
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
throws Throwable {
// Use reflection to invoke the method.
// 通过反射机制来获得相应的方法,并调用invoke
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
}
CglibAopProxy#getProxy
class CglibAopProxy implements AopProxy, Serializable {
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 1.拿到要代理目标类
Class> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
// proxySuperClass默认为rootClass
Class> proxySuperClass = rootClass;
// 这里判断rootClass是否是Cglib代理所产生的类(内部判断rootClass的className是否包含$$)
// 如果rootClass是被Cglib代理过的,获取rootClass的父类作为proxySuperClass
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class>[] additionalInterfaces = rootClass.getInterfaces();
for (Class> additionalInterface : additionalInterfaces) {
// 将父类的接口也添加到advised的interfaces属性
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 方法校验,final方法不能被代理,记录日志
// 2.校验proxySuperClass,主要是校验方法是否用final修饰、跨ClassLoader的包可见方法,如果有将警告写入日志
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
// 3.创建和配置Cglib Enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// superclass为被代理的目标类proxySuperClass,通过名字可以看出,生成的代理类实际上是继承了被代理类
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 4.获取所有要回调的拦截器
// 通过callbacks设置拦截器链
// spring在这里考虑了很多种情况,将所有callback放到一个数组中。
// 而在某些特定场景下,spring还对回调进行了优化,生成新的回调函数,追加到callbacks数组中。
Callback[] callbacks = getCallbacks(rootClass);
Class>[] types = new Class>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
// 设置回调过滤器,修正后的拦截器map和偏移量在这里传进去
// 在上面调用getCallbacks之后,此时仅填充fixedInterceptorMap
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
// 生成代理类实例
// 5.生成代理类并创建代理实例,返回代理实例
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
}
getCallbacks
获取所有要回调的拦截器
class CglibAopProxy implements AopProxy, Serializable {
private Callback[] getCallbacks(Class> rootClass) throws Exception {
// Parameters used for optimization choices...
// 1.用于优化选择的参数
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
// 最常用的就是这个拦截器DynamicAdvisedInterceptor
// 2.使用AdvisedSupport作为参数,创建一个DynamicAdvisedInterceptor(“aop”拦截器,用于AOP调用)
// this.advised就是之前创建CglibAopProxy时传进来的ProxyFactory(ProxyCreatorSupport子类)
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
// 原始的7种callback
// 3.将aop拦截器添加到mainCallbacks中
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
// 如果目标类是不可变的(getTarget()方法返回的对象是否一直是同一个,也就是说对单例对象而言,isStatic都返回true),
// 且代理对象被冻结(isFrozen属性设置为true),那么spring将会采取优化,在callbacks数组中增加了新的回调,
// 使用修正后的增强链把aop调用直接转发到目标方法来进行一些优化,也就是说此时代理将不生效
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
// 把默认的7种callback和修正后的callback合并到一个数组中返回
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
}
class CglibAopProxy implements AopProxy, Serializable {
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class> targetClass = (target != null ? target.getClass() : null);
// 这里获取拦截器链的方式与jdk动态代理方式调用了同一个方法
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
// chain 是空的,说明不需要被织入横切逻辑,直接执行被代理的方法实例本身
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
// 获取目标对象的调用链逻辑,并且对该链进行调用
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
//处理返回值,并返回。
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// 如果TargetSource不是静态的,
// 则调用其releaseTarget()方法将生成的目标对象释放
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
// 处理AopContext中保存的当前代理对象
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
}
用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支 持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。
实用命令实例
默认启动
tcpdump
普通情况下,直
MO= Mobile originate,上行,即用户上发给SP的信息。MT= Mobile Terminate,下行,即SP端下发给用户的信息;
上行:mo提交短信到短信中心下行:mt短信中心向特定的用户转发短信,你的短信是这样的,你所提交的短信,投递的地址是短信中心。短信中心收到你的短信后,存储转发,转发的时候就会根据你填写的接收方号码寻找路由,下发。在彩信领域是一样的道理。下行业务:由SP
import java.util.Arrays;
import java.util.Random;
public class MinKElement {
/**
* 5.最小的K个元素
* I would like to use MaxHeap.
* using QuickSort is also OK
*/
public static void
添加没有默认值:alter table Test add BazaarType char(1)
有默认值的添加列:alter table Test add BazaarType char(1) default(0)
删除没有默认值的列:alter table Test drop COLUMN BazaarType
删除有默认值的列:先删除约束(默认值)alter table Test DRO
Spring Boot 1.2.4已于6.4日发布,repo.spring.io and Maven Central可以下载(推荐使用maven或者gradle构建下载)。
这是一个维护版本,包含了一些修复small number of fixes,建议所有的用户升级。
Spring Boot 1.3的第一个里程碑版本将在几天后发布,包含许多