springAop的简单介绍
AOP是处理一些横切性问题,AOP的编程思想就是把这些问题和主业务逻辑分开,达到与主业务逻辑解耦的目的。使代码的重用性和开发效率更高。比如在日志记录、权限校验等场景,使用aop实现对代码无入侵效率更高。
- spring aop中的概念
Aspect | 切面 |
Join Point | 连接点 在Spring Aop中总是代表一次方法的执行 |
Advice | 通知,在连接点上执行的动作 |
PointCut | 切入点,说明如何匹配连接点 |
Introduction | 引入,为实现类型声明额外的方法和属性 |
Target object | 目标对象 |
AOP proxy | AOP代理对象,JDK动态代理或CGLIB代理 |
Weaving | 织入,连接切面与目标对象或类型创建代理的过程 |
- spring aop与AspectJ
springAop、AspectJ都是Aop的实现,SpringAop有自己的语法,但是语法复杂,所以SpringAop借助了AspectJ的注解,但是底层实现还是自己的。在springAop中启用AspectJ支持需要添加注释@EnableAspectJAutoProxy。
Aop的源码解析
首先声明一个切面:
@Aspect
@Component
public class TestAspect {
@Pointcut("execution(* test.aop.*.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void advice(){
System.out.println("aop before---");
}
}
编写一个测试类
@ComponentScan("test")
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
@Component
public class TestService implements I{
@Override
public void query() {
System.out.println("query-demo");
}
}
public class TestDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
I i = (I) applicationContext.getBean("testService");
System.out.println(i instanceof TestService);
i.query();
}
}
在spring的初始化过程中会将AppConfig的ComponentScan标注的的包下的bean都加载在上下文容器中,bean初始化bean的时候会调用AbstractBeanFactory的getBean方法,如果bean存在容器中就返回不存在执行创建逻辑。
AbstractBeanFactory.getBean()方法调用了doGetBean()方法
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 如果是别名则转换为规范的bean名称
String beanName = transformedBeanName(name);
Object beanInstance;
// 从容器中获取bean实例,在创建bean的过程中获取到的sharedInstance肯定是null
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
......
}
else {
......
// 这部分的内容获取到的都是null直接跳过
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
// 如果目标类有父类,会去获取父类的BeanDefinition和目标类的BeanDefinition整合到一起
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
// 重点在这里,目标对象为单例,前面的步骤大部分判断条件都不会进去,目标对象的bean在这里创建
sharedInstance = getSingleton(beanName, () -> {
try {
// *创建bean*
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
......
return adaptBeanInstance(name, beanInstance, requiredType);
}
createBean方法又调用到AbstractAutowriteCapableBeanFactory中的createBean方法
在createBean的方法中会执行doCreateBean方法
AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
......
// 执行一些初始化前操作
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
......
}
而doCreateBean方法中,首先创建beanWrapper实例化bean,然后在初始化bean的时候执行BeanPostProcessors的postProcessAfterInitialization的回调创建代理类
AbstractAutowireCapableBeanFactory
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建Bean,当前的bean还不是代理类
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
......
Object exposedObject = bean;
try {
// 实现依赖注入
populateBean(beanName, mbd, instanceWrapper);
// 在这里有一个Aop自动生成的后置处理,生成代理类
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
......
return exposedObject;
}
在方法initializeBean(beanName, exposedObject, mbd)中有一个applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)的方法,调用初始化后的后置处理
AbstractAutowireCapableBeanFactory
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 在这里有一个AnnotationAwareAspectJAutoProxyCreator自动生成的后置处理,生成代理类
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
在testService的后置处理进行时,会有一个特殊的后置处理,通过这个后置处理生成代理类
AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization()方法又调用了AbstractAutoProxyCreator的postProcessAfterInitialization()方法,在wrapIfNecessary()中执行createProxy(),调用proxyFactory.getProxy创建代理对象
AbstractAutoProxyCreator
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// No proxyTargetClass flag enforced, let's apply our default checks...
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 获取切面中的advice即所有通知
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 创建代理对象
return proxyFactory.getProxy(classLoader);
}
代理类工厂ProxyFactory
ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
其中最重要的是createAopProxy()返回代理类AopProxy执行相应的getProxy方法创建代理类
在DefaultAopProxyFactory中可以看到是使用JDK动态代理还是CGLIB动态代理
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
...
}
可以看出在默认情况下如果目标类实现了接口则使用jdk动态代理,没有实现接口使用cglib动态代理
在JdkDynamicAopProxy和CglibAopProxy中都有相应的getProxy()方法创建代理类
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
...
}
使用jdk生成代理的方法Proxy.newProxyInstance()
CglibAopProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
......
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
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
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
使用字节码增强工具Enhancer创建一个代理类
代理类是如何执行的
JdkDynamicAopProxy实现了JDK动态代理执行所需要的接口InvocationHandler,生成代理类时
Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this)
InvocationHandler的实现类也指向了JdkDynamicAopProxy,因此,代理类调用的时候会先执行JdkDynamicAopProxy中的invoke()方法。在invoke方法中,会获取满足条件的所有切面的advice,然后组成一个调用链chain,然后invocation.proceed()按照责任链的模式依次执行一个切点的前置、后置等方法
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 {
......
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
// 获取满足条件的所有切面的advice,然后组成一个调用链chain,然后依次执行一个切点的前置、后置等方法
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// 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.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
....
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
....
}
同理使用CGLIB动态代理,是在创建代理类的时候enhancer设置了callback,最后执行callback的MethodInterceptor的intercept方法