Spring 进阶

Spring 进阶

官网文档

一. Spring 简介

  1. Spring 技术点:

Core: IoC Container, Events, Resources, i18n, Validation, Data Binding, Type Conversion, SpEL, AOP.

  1. Spring IOC 应该添加的依赖包
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.4.RELEASE</version>
        </dependency>

二. Spring容器的初始化

public static void main(String[] args) {
        //init(利用注解上下文) 
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        BeanTest bean = applicationContext.getBean(BeanTest.class);
        System.out.println(bean);
    }
//AnnotationConfigApplicationContext的有参方法,调用无参方法
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
	//1.初始化beanFactory
	this();
	register(componentClasses);
	refresh();
}

1.初始化beanFactory

//AnnotationConfigApplicationContext的无参方法
public AnnotationConfigApplicationContext() {
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}
//AnnotationConfigApplicationContext extends GenericApplicationContext 会调用父类的无参方法
//父类无参构造方法初始化了beanFactory
public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}

/** Map of bean definition objects, keyed by bean name. */
// DefaultListableBeanFactory 中有个 beanDefinitionMap 
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
  1. refresh
public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//在Spring的环境中去执行已经被注册的factory processors
				// 设置执行自定义的ProcessBeanFactory和spring内部自定义的
				//scan => beanDefinition=> put beanDefinitionMap =>  
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//注册beanPostProcessors
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//new 对象 
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

一. Spring bean 的生命周期

bean创建过程

create A ==> new 对象 ==> Aop ==> lifeclyCallBack ==> 自动注入… ==> bean

  1. 普通类的创建过程 new
  2. Spring创建类的过程
  1. 解析类
  2. 将类信息通过beanDefinition存到beanDefinitionMap中
  3. 经过一系列的beanPostProcessor操作 实例化bean对象 finishBeanFactoryInitialization(beanFactory);
public interface BeanPostProcessor {
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}
  1. 循环依赖问题

A 依赖 B ; B 依赖 A 即 A => B => A => B (为什么不会产生死循环)

createA => new A => autoB(getB) => createB => new B => autoA(getA) => 返回a对象
在getA中 通过 isSingletonCurrentlyInCreation() 方法,判断这个bean是否在创建

// Instantiate all remaining (non-lazy-init) singletons.
//new 对象 
finishBeanFactoryInitialization(beanFactory);
	/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		//实例化bean
		beanFactory.preInstantiateSingletons();
	}
	//beanFactory.preInstantiateSingletons();的具体过程
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//遍历所有类
		for (String beanName : beanNames) {
			//beanDefinitionMap.get(beanName)
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//判断这个bean是不是抽象,是不是单例,是不是懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//如果是factoryBean, beanName前面加上"&"
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					//如果不是factoryBean 调用getBean(beanName)方法获取bean对象(这个方法中包含createBean)
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

getBean(beanName) 实际是调用doGetBean()方法,进行创建或者获取bean对象

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * @param name the name of the bean to retrieve
	 * @param requiredType the required type of the bean to retrieve
	 * @param args arguments to use when creating a bean instance using explicit arguments
	 * (only applied when creating a new instance as opposed to retrieving an existing one)
	 * @param typeCheckOnly whether the instance is obtained for a type check,
	 * not for actual use
	 * @return an instance of the bean
	 * @throws BeansException if the bean could not be created
	 */
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		//对名字进行验证
		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				//判断该bean是否在创建过程中(主要解决循环依赖问题)
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				final 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()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							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;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}
	/** Cache of singleton objects: bean name to bean instance. */
	//存放完全初始化好的bean,能直接使用
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

二. BeanPostProcessor

beanPostProcessor(后置处理器): 通过代理模式的方法,给 对象 添加一系列初始化的操作

public interface BeanPostProcessor {
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}

四. Spring beanFactory 和 factoryBean 的区别

五.Spring AOP

  1. Spring AOP 的八大组件
  1. Aspect
  2. Join point. 连接点 要关注和增强的方法即我们要作用的点
  3. Advice 通知 即对作用点的具体增强操作
  4. Pointcut 切面 所有连接点的集合
  5. ntroduction
  6. Target object: 目标对象,原始对象
  7. AOP proxy 代理对象 通过动态代理模式生成的代理对象(两种方法: 默认JDK动态代理 , Cglib)
  8. Weaving 织入 连接advice跟target object 组成 aop proxy 的过程
  1. 开启@AspectJ 语法支持(两种方法)
    首先添加依赖 aspectjweaver.jar
  1. xml: aop:aspectj-autoproxy/
    2.@EnableAspectJAutoProxy
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
}
  1. Spring AOP 切点 的几种定义方式

execution: For matching method execution join points. This is the primary pointcut designator to use when working with Spring AOP.
针对方法, 最小粒度是方法

within: Limits matching to join points within certain types (the execution of a method declared within a matching type when using Spring AOP).
针对declared 路径,(说明)

this: Limits matching to join points (the execution of methods when using Spring AOP) where the bean reference (Spring AOP proxy) is an instance of the given type.
匹配当前代理类是否是该接口/类或其子类
这里有一个大坑,spring 实现代理模式有两种: (假设现在有 interface A 以及 class B impl A)
默认使用jdk内置的代理模式,class C extends Proxy implements interface A (然后把B依赖注入进去了) 这种时候 Proxy C 只能强转成interface A不能强转成class B
第二种是 cglib 实现动态代理, class C extends class B implements interface A 所以Proxy C 能强转成 class B 又能强转成 interface A (需要进行设置@EnableAspectJAutoProxy(proxyTargetClass = true))

target: Limits matching to join points (the execution of methods when using Spring AOP) where the target object (application object being proxied) is an instance of the given type.
针对 target object目标类(原类)
匹配目标类是否是该接口/类或其子类

args: Limits matching to join points (the execution of methods when using Spring AOP) where the arguments are instances of the given types.
针对arguments(参数)类型

@target: Limits matching to join points (the execution of methods when using Spring AOP) where the class of the executing object has an annotation of the given type.
Any join point (method execution only in Spring AOP) where the target object has a @Transactional annotation

@args: Limits matching to join points (the execution of methods when using Spring AOP) where the runtime type of the actual arguments passed have annotations of the given types.
Any join point (method execution only in Spring AOP) which takes a single parameter, and where the runtime type of the argument passed has the @Classified annotation:

@within: Limits matching to join points within types that have the given annotation (the execution of methods declared in types with the given annotation when using Spring AOP).
Any join point (method execution only in Spring AOP) where the declared type of the target object has an @Transactional annotation:

@annotation: Limits matching to join points where the subject of the join point (the method being executed in Spring AOP) has the given annotation.
Any join point (method execution only in Spring AOP) where the executing method has an @Transactional annotation:

这些语法之间可以使用&& (and), || (or), and ! (negation)进行运算
这里简单讲一下 excution的使用

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
* execution(修饰符? 返回值类型 声明?方法名(参数类型)抛出异常?)
* "?"代表可有可无
* @execution (* com.lucifer.cn.service..*.*(..))  ('省略修饰符' '*':所有非返回值类型
* 'com.lucifer.cn.service.' : declaring-type-pattern
* 'com.lucifer.cn.service..':声明是哪个包下的('.'只指他这个包直接下的 '..'包含他下面的子包的)  '*'所有的类' 第二个'*':所有的方法 '(..)':不限定参数类型)
* execution(* com.xyz.service..*.*(..)): The execution of any method defined in the service package or one of its sub-packages
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值