Spring菜鸟教你看源码冲面试

Spring

类的初始化和实例化的不同

IOC

探究spring的IOC容器

DefaultListableBeanFactory是最终实现类,在代码中可以找到HashMap的影子;IOC容器就是用HashMap装的Bean;

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Nullable
	private static Class<?> javaxInjectProviderClass;

	static {
		try {
			javaxInjectProviderClass =
					ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - Provider interface simply not supported then.
			javaxInjectProviderClass = null;
		}
	}

	/** Map from serialized id to factory instance. */
	private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
			new ConcurrentHashMap<>(8);

	/** Optional id for this factory, for serialization purposes. */
	@Nullable
	private String serializationId;

	/** Whether to allow re-registration of a different definition with the same name. */
	private boolean allowBeanDefinitionOverriding = true;

	/** Whether to allow eager class loading even for lazy-init beans. */
	private boolean allowEagerClassLoading = true;

	/** Optional OrderComparator for dependency Lists and arrays. */
	@Nullable
	private Comparator<Object> dependencyComparator;

	/** Resolver to use for checking if a bean definition is an autowire candidate. */
	private AutowireCandidateResolver autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;

	/** Map from dependency type to corresponding autowired value. */
	private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

	/** Map of bean definition objects, keyed by bean name. */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

	/** Map from bean name to merged BeanDefinitionHolder. */
	private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256);

	/** Map of singleton and non-singleton bean names, keyed by dependency type. */
	private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

	/** Map of singleton-only bean names, keyed by dependency type. */
	private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

	/** List of bean definition names, in registration order. */
	private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

	/** List of names of manually registered singletons, in registration order. */
	private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

	/** Cached array of bean definition names in case of frozen configuration. */
	@Nullable
	private volatile String[] frozenBeanDefinitionNames;
................
...........
}

BeanFactory:主要方法为getBean(String beanName),该方法根据Bean名称从容器返回对应的Bean

BeanFactory是接口,提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范,

发现BeanFactory是Spring的IOC容器核心接口,它的职责包括,实例化,有很多的实现类;

原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等

那么BeanFactroy是否有AOP的影子呢?

找到BeanFactroyAware接口看到很多关键字有proxy类似代理的接口

so 猜想是否跟AOP(面向切面,动态代理)有关

然后点进去其中一个方法(AbstractAutoProxyCreator),发现引入很多跟AOP相关的包

import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.AopInfrastructureBean;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.ProxyProcessorSupport;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.target.SingletonTargetSource;

往下看看这个类,做了什么?找几个方法出来;

看看类的注释

此类区分通用拦截器(由创建的所有代理共享)和特定拦截器:每个bean实例唯一。不需要任何通用拦截器。如果存在,则使用interceptorNames属性设置它们。
与{@link org.springframework.aop.framework.ProxyFactoryBean}一样,使用当前工厂中的拦截器名称而不是bean引用来正确处理原型顾问程序和拦截器例如,以支持有状态的混合。{@link #set InterceptorNames interceptorNames}条目支持任何建议类型。 如果有大量的豆需要用类似的代理包装,即委托给相同的拦截器,则这种自动代理特别有用。 代替x个目标bean的x个重复代理定义,您可以在bean工厂注册一个这样的后处理器,以达到相同的效果

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
  /**
	 *设置公共拦截器。这些必须是当前工厂中的bean名称
	 */
	public void setInterceptorNames(String... interceptorNames) {
		this.interceptorNames = interceptorNames;
	}
/**
	为给定的bean创建一个AOP代理
	 */
	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()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);
		proxyFactory.setFrozen(this.freezeProxy);

		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		return proxyFactory.getProxy(getProxyClassLoader());
	}

}

AbstractAutoProxyCreator类关系UML图

说明AOP横切在Bean的生命周期中


AOP

Spring 通过 AbstractAutoProxyCreator 来创建 AOP 代理,AbstractAutoProxyCreator 是一个抽象类,它实现了 BeanPostProcessor 接口,用于在 bean 初始化完成之后创建它的代理(从上面IOC容器创建Bean过程中有点体现);

在AbstractAutoProxyCreator类关系UML图中找到一个特殊的接口—>BeanPostProcessor

划重点:

  • 与工厂挂钩,允许自定义修改新bean实例,如检查标记接口或使用代理包装bean
  • 普通的{@code BeanFactory}允许以编程方式注册后处理器,并将其应用于通过bean工厂创建的所有bean中;跟上面的AOP横切BeanFactroy联系上了;
/**
 工厂挂钩,允许自定义修改新bean实例-例如,检查标记接口或使用代理包装bean。 <p>通常,通过标记接口*或类似对象填充bean的后处理器将实现{@link #postProcessBeforeInitialization},而使用代理包装bean的后处理器通常将实现{@link #postProcessAfterInitialization}。 <h3>注册</h3> <p> {@ code ApplicationContext}可以在其bean定义中自动检测{@code BeanPostProcessor} bean,并将这些后处理器应用于随后创建的任何bean。普通的{@code BeanFactory}允许以编程方式注册后处理器,并将其应用于通过bean工厂创建的所有bean
 */
public interface BeanPostProcessor {

	/**
	 在任何bean 初始化回调(如InitializingBean的{@code afterPropertiesSet} 或自定义的init-method)之前,将此{@code BeanPostProcessor}应用于给定的新bean实例<i> </ i>。该bean将已经用属性值填充。 返回的bean实例也可能是原始实例的包装;
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
在任何bean 初始化回调(例如InitializingBean的{@code afterPropertiesSet} 或自定义的初始化方法)之后,将此{@code BeanPostProcessor}应用于给定的新bean实例。该bean将已经用属性值填充。 返回的bean实例可能是原始实例的包装。 对于FactoryBean,将为FactoryBean 实例和由FactoryBean创建的对象(从Spring 2.0开始)调用此回调。后处理器可以通过相应的{@code bean instanceof FactoryBean}检查来决定是应用到FactoryBean还是创建的对象,还是两者都应用。
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

在来看这张图(IOC容器工作过程) BeanPostProcessor就是AOP切入的位置,处在对象的生命周期中;

BeanFactoryPostProcessor(初始化Bean,如上图)

public interface BeanFactoryPostProcessor {
	/**
	在标准初始化之后,修改应用程序上下文的内部bean工厂。所有bean定义都将被加载,但是还没有实例化bean *。这甚至可以覆盖或添加*属性,甚至可以用于初始化bean。
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}


另外提点东西(来自面试) BeanFactory 简介以及它 和FactoryBean的区别(阿里面试)

FactoryBean接口是什么?

看看官方注释:

在BeanFactory中的对象实现的接口,这些对象本身是个单个对象的工厂,如果这些对象实现FactoryBean接口,它将用作对象公开的工厂,而不是直接将自身公开;

好像还是有点蒙吧看看其他解释

FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似
FactoryBean接口用的是Class<?> getObjectType();可以理解为高级定制Bean;

看FactoryBean接口抽象类(AbstractFactoryBean)

public abstract class AbstractFactoryBean<T>
		implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
	/** Logger available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());
	private boolean singleton = true;
	@Nullable
	private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
	@Nullable
	private BeanFactory beanFactory;
	private boolean initialized = false;
	@Nullable
	private T singletonInstance;
	@Nullable
	private T earlySingletonInstance;

	/**
   设置是否应该创建一个单例,或者在每个请求上创建一个新对象*否则。默认值为{@code true}(单例)。
	 */
	public void setSingleton(boolean singleton) {
		this.singleton = singleton;
	}
	@Override
	public boolean isSingleton() {
		return this.singleton;
	}
	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
		this.beanClassLoader = classLoader;
	}
	@Override
	public void setBeanFactory(@Nullable BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}
	/**
	 返回运行该bean的BeanFactory
	 */
	@Nullable
	protected BeanFactory getBeanFactory() {
		return this.beanFactory;
	}

	/**
   从运行该bean的BeanFactory获取一个bean类型转换器
	 */
	protected TypeConverter getBeanTypeConverter() {
		BeanFactory beanFactory = getBeanFactory();
		if (beanFactory instanceof ConfigurableBeanFactory) {
			return ((ConfigurableBeanFactory) beanFactory).getTypeConverter();
		}
		else {
			return new SimpleTypeConverter();
		}
	}
  /**
    公开单例实例(用于通过“早期单例”代理访问)。返回此FactoryBean持有的单例实例
	 */
	@Nullable
	private T getSingletonInstance() throws IllegalStateException {
		Assert.state(this.initialized, "Singleton instance not initialized yet");
		return this.singletonInstance;
	}
}

看完FactoryBean接口抽象类(AbstractFactoryBean)基本的代码后,发现什么?

FactoryBean基于BeanFactory,FactoryBean是一个能生产或者修饰对象生成的工厂Bean;

FactoryBean中定义了一个Spring Bean的很重要的三个特性:是否单例、Bean类型、Bean实例

ApplicationContext接口,

由BeanFactory接口派生而来

看到ApplicationContext接口

提供应用程序配置的中央接口。在应用程序运行时为只读,但如果实现支持,则可以重新加载。
ApplicationContext提供:

  • 用于访问应用程序组件的Bean工厂方法。继承自{@link org.springframework.beans.factory.ListableBeanFactory}。
  • 以通用方式加载文件资源的能力。继承自{@link org.springframework.core.io.ResourceLoader}接口。
  • 将事件发布到注册的侦听器的能力。继承自{@link ApplicationEventPublisher}接口。
  • 解决消息的能力,支持国际化。继承自{@link MessageSource}接口。
  • 从父上下文继承。在后代上下文中的定义将始终优先。例如,这意味着整个Web应用程序都可以使用单个父上下文,而每个servlet都有自己的子上下文,而该子上下文独立于任何其他servlet的子上下文。
  • 除了标准的{@link org.springframework.beans.factory.BeanFactory}生命周期功能之外,ApplicationContext实现还检测并调用{@link ApplicationContextAware} Bean以及{@link ResourceLoaderAware },{@link ApplicationEventPublisherAware}和{@link MessageSourceAware} bean。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

	/**
   返回此应用程序上下文的唯一ID
	 */
	@Nullable
	String getId();

	/**
	返回此上下文所属的已部署应用程序的名称
	 */
	String getApplicationName();

	/**
   返回此上下文的显示名称
	 */
	String getDisplayName();

	/**
	返回首次加载此上下文时的时间戳
	 */
	long getStartupDate();

	/**
	 返回父级上下文,如果没有父级,则返回{@code null}
	 */
	@Nullable
	ApplicationContext getParent();

	/**
	针对此上下文公开AutowireCapableBeanFactory功能。 * <p>应用程序代码通常不使用此功能,除非是为了*初始化存在于应用程序上下文之外的bean实例,*将Spring bean生命周期(全部或部分)应用于它们。 * <p>或者,通过{@link ConfigurableApplicationContext}接口公开的内部BeanFactory也提供对{{link AutowireCapableBeanFactory}接口的访问。本方法主要*用作ApplicationContext接口上的便捷特定工具。 * <p> <b>注意:从4.2开始,在关闭应用程序上下文之后,此方法将始终抛出IllegalStateException *。</ b>在当前的Spring Framework *版本中,只有可刷新的应用程序上下文才具有这种行为;从4.2开始,*所有应用程序上下文实现都将必须遵守。 * @为此上下文返回AutowireCapableBeanFactory *如果上下文不支持{@link AutowireCapableBeanFactory}接口,或者尚不具有支持自动连线功能的bean工厂,则抛出IllegalStateException(例如,如果{@code refresh()}具有*从未调用过),或者上下文已经关闭* @see ConfigurableApplicationContext#refresh()* @see ConfigurableApplicationContext#getBeanFactory()* /
	 */
	AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

ApplicationContext接口UML类图

ApplicationContext有两个主要的实现类:ClassPathXmlApplicationContext:默认从类路径加载配置文件,还有FileSystemXmlApplicationContext:默认从文件系统中装载配置文件

WebApplicationContext

提供Web应用程序配置的界面。在应用程序运行时为只读,但是如果实现支持,则可以重新加载。此接口在通用ApplicationContext接口中添加了一个{@code getServletContext()}方法,并定义了一个众所周知的应用程序属性名称,该名称必须在引导过程中绑定到根上下文。类似于通用应用程序上下文,Web应用程序上下文是分层的。 每个应用程序只有一个根上下文,而应用程序中的每个servlet(包括MVC框架中的调度程序servlet)都有自己的子上下文。除了标准的应用程序上下文生命周期功能外,WebApplicationContext实现还需要检测{@link ServletContextAware} bean,并相应地调用{@code setServletContext}方法

public interface WebApplicationContext extends ApplicationContext {

	/**
	Context属性,用于在成功启动时将根WebApplicationContext绑定到该属性。 * <p>注意:如果根上下文的启动失败,则此属性可以包含*异常或错误作为值。使用WebApplicationContextUtils方便*查找根WebApplicationContext。
	 */
	String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

	/**
	请求范围的范围标识符:“ request”。 *除了标准范围“ singleton”和“ prototype”之外,还受支持。
	 */
	String SCOPE_REQUEST = "request";

	/**
	会话范围的范围标识符:“session”。 *除了标准范围“ singleton”和“ prototype”之外,还受支持。
	 */
	String SCOPE_SESSION = "session";

	/**
	全局Web应用程序范围的范围标识符:“application”。 *除了标准范围“ singleton”和“ prototype”之外,还受支持。
	 */
	String SCOPE_APPLICATION = "application";

	/**
	工厂中ServletContext环境Bean的名称
	 */
	String SERVLET_CONTEXT_BEAN_NAME = "servletContext";

	/**
	工厂中ServletContext init-params环境Bean的名称
	 */
	String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";

	/**
	工厂中ServletContext属性环境bean的名称
	 */
	String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";

	/**
	返回此应用程序的标准Servlet API ServletContext
	 */
	@Nullable
	ServletContext getServletContext();
}

WebApplicationContext的UML类图(从图中可以发现WebApplicationContext扩展了ApplicationContext的功能,ApplicationContext扩展了BeanFactory的功能。)

这几个接口间的区别

BeanFactory和ApplicationContext, WebApplicationContext初始化区别:BeanFactory在初始化容器时并没有实例化Bean,而是在第一次访问到目标Bean时才实例化该Bean;而ApplicationContext会在初始化上下文时实例化所有的单例的Bean。WebApplicationContext的初始化需要servletContext实例(getServletContext();),即初始化需要拥有web容器,我们需要在web.xml中配置自启动的servlet或web容器监听器(servletContextListener)

Bean的作用域

在BeanFactory和ApplicationContext中的Bean的作用域有两种:
singleton和prototype,
在WebApplicationContext中的Bean的作用域有三种:request,session和globalSession。
singleton:在IOC容器中仅存在一个Bean实例,Bean以单例方式存在,外部引用都指向这个Bean
prototype:每次调用Bean都返回一个新实例
request:在同一个Http请求的Bean相同,每个Http请求创建一个新的Bean。
session:在Http请求对应同一个session时对应同一个Bean。
globalSession:一般的web应用中globalSession等价于session,只有在portlet web应用中才存在globalSession概念。

到此这篇关于Spring菜鸟教你看源码冲面试的文章就介绍到这了,更多相关Spring源码内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • idea2020导入spring5.1的源码的详细教程

    1.先来说下导入环境和工具:     java版本:1.8     idea: idea2020     gradle:gradle5.3 2.gradle的安装     idea导入spring的源码时,每次构建的时候都会去下载gradle,所以如果我们能提前下好gradle可以提高构建速度.     gradle下载地址:https://services.gradle.org/distributions/     上面放的地址可以找到gradle的所有版本.(注意:构建spring源码是有版

  • SpringSecurity 默认表单登录页展示流程源码

    SpringSecurity 默认表单登录页展示流程源码 本篇主要讲解 SpringSecurity提供的默认表单登录页 它是如何展示的的流程, 涉及 1.FilterSecurityInterceptor, 2.ExceptionTranslationFilc,xmccmc,ter , 3.DefaultLoginPageGeneratingFilter 过滤器, 并且简单介绍了 AccessDecisionManager 投票机制  1.准备工作(体验SpringSecurity默认表单认证

  • Spring+SpringMVC+JDBC实现登录的示例(附源码)

    有一位程序员去相亲的时候,非常礼貌得说自己是一名程序员,并解释自己是做底层架构的,于是女方听到"底层"两个字,就一脸嫌弃:什么时候能够到中高级? 用久了框架,把原生都忘记了,本章从零开始,熟悉一遍JDBC实现增删改查 开发环境 jdk 1.8 Maven 3.6 Spring.SpringMVC 4.3.18 dbcp2 jsp Idea 创建项目 创建项目时,我们选择传统的Maven项目结构 创建项目时不要选择任何模板,直接点Next 填写包名及项目名Next --> Fini

  • spring实现动态切换、添加数据源及源码分析

    前言 对于数据量在1千万,单个mysql数据库就可以支持,但是如果数据量大于这个数的时候,例如1亿,那么查询的性能就会很低.此时需要对数据库做水平切分,常见的做法是按照用户的账号进行hash,然后选择对应的数据库. 最近公司项目需求,由于要兼容老系统的数据库结构,需要搭建一个 可以动态切换.添加数据源的后端服务. 参考了过去的项目,通过配置多个SqlSessionFactory 来实现多数据源,这么做的话,未免过于笨重,而且无法实现动态添加数据源这个需求 通过 spring AbstractRo

  • IDEA2020.1构建Spring5.2.x源码的方法

    内容概览 使用IDEA2020.1构建Spring5.2.x源码 环境 源码:spring5.2.xjdk11.08idea2020.1 spring spring5.2.x源码下载地址 gradle 下载 查看spring使用的gradle版本,这里要记得将distributionUrl指向本地的gradle包,不然还是会去下载的. distributionUrl=file:///H:/download/gradle-5.6.4-bin.zip gradle下载地址 安装 window下,配置

  • 基于spring-boot和docker-java实现对docker容器的动态管理和监控功能[附完整源码下载]

    docker简介 Docker 是一个开源的应用容器引擎,和传统的虚拟机技术相比,Docker 容器性能开销极低,因此也广受开发者喜爱.随着基于docker的开发者越来越多,docker的镜像也原来越丰富,未来各种企业级的完整解决方案都可以直接通过下载镜像拿来即用.因此docker变得越来越重要. 本文目的 本文通过一个项目实例来介绍如果通过docker对外接口来实现对docker容器的管理和监控. 应用场景: 对服务器资源池通过docker进行统一管理,按需分配资源和创建容器,达到资源最大化利

  • Idea 搭建Spring源码环境的超详细教程

    本篇主要讲解如何使用Ideal 搭建Spring的源码环境,想必大家都会多多少少去看过Spring的部分源码,一般我们都是直接点进某个Spring类 然后Idea上面去下载 ,但是确实比较麻烦,而且不能添加自己对源码的注释 理解 ,本篇就来解决这个问题,手把手使用Idea 搭建Spring framework ,并且直接在Spring framework项目中添加我们自己的module 来验证环境是否正确. 本过程会比较耗时 而且容易出错 慢慢来吧. 1. clone spring-framew

  • Spring菜鸟教你看源码冲面试

    Spring 类的初始化和实例化的不同 IOC 探究spring的IOC容器 DefaultListableBeanFactory是最终实现类,在代码中可以找到HashMap的影子:IOC容器就是用HashMap装的Bean; public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefin

  • Spring循环引用失败问题源码解析

    目录 前言: 例子 启动容器 加载circulationa AbstractBeanFactory 最终调用BeanDefinitionValueResolver circulationb加载分析 前言: 之前我们有分析过Spring是怎么解决循环引用的问题,主要思路就是三级缓存: Spring在加载beanA的时候会先调用默认的空构造函数(在没有指定构造函数实例化的前提下)得到一个空的实例引用对象,这个时候没有设置任何值,但是Spring会用缓存把它给提前暴露出来,让其他依赖beanA的bea

  • 超详细的Intellij IDEA 看源码必备技能

    最近正好也没什么可忙的,就回过头来鼓捣过去的知识点,到Servlet部分时,以前学习的时候硬是把从上到下的继承关系和接口实现记得乱七八糟. 这次利用了IDEA的diagram,结果一目了然,也是好用到炸裂,就此分享. 1.查看图形形式的继承链 在你想查看的类的标签页内,点击右键,选择 Diagrams,其中有 show 和 show ... Popup,只是前者新建在标签页内,后者以浮窗的形式展示: 实际上,你也可以从左边的项目目录树中,对你想查看的类点击右键,同样选择Diagrams,效果是一

  • Mybatis一级缓存和结合Spring Framework后失效的源码探究

    1.在下面的案例中,执行两次查询控制台只会输出一次 SQL 查询: mybatis-config.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"

  • 话说Spring Security权限管理(源码详解)

    最近项目需要用到Spring Security的权限控制,故花了点时间简单的去看了一下其权限控制相关的源码(版本为4.2). AccessDecisionManager spring security是通过AccessDecisionManager进行授权管理的,先来张官方图镇楼. AccessDecisionManager AccessDecisionManager 接口定义了如下方法: //调用AccessDecisionVoter进行投票(关键方法) void decide(Authent

  • Spring EnableAsync注解异步执行源码解析

    目录 概述 @EnableAsync 分析 ProxyAsyncConfiguration 分析 AsyncAnnotationBeanPostProcessor 分析 AsyncAnnotationAdvisor 分析 Advice 构建 Pointcut 构建 AnnotationAsyncExecutionInterceptor 分析 AsyncTaskExecutor 查找 Callable 任务封装 doSubmit 异步执行方法 总结 概述 基于 Spring Framework v

  • IE view-source 无法查看看源码 JavaScript看网页源码 原创

    第一种:view-source法 view-source是一种协议,早期基本上每个浏览器都支持这个协议.但是不知道什么原因,从IE6 Beta2以后IE就不再支持此协议了.这个方法现在只能用在FireFox浏览器上使用了! 使用方法:在浏览器地址栏中输入 view-source: 回车即可看到网页的源代码了. 第二种:JavaScript法 这种方法似乎也不是通用的,在IE6和Opere浏览器上试验成功,但是在FireFox浏览器上就没成功! 使用方法:在浏览器地址栏中输入 复制代码 代码如下:

  • 源码解析Spring 数据库异常抽理知识点总结

    数据库为:H2 如果需要处理特定 SQL 异常,比如 SQL 语句错误,这个时候我们应该怎么办? 查看 SQLException 源码,我们可以发现两个重要的方法. SQLException.getErrorCode:返回数据库特定的错误码,由数据库厂商制定,不同厂商错误码不同.如重复主键错误码在 MySQL 中是 1062,而在 Oracle 中却是 1. SQLException.getSQLState:返回 XOPEN 或 SQL:2003 制定的错误码规范.数据库厂商会将不同错误消息映射

  • spring获取bean的源码解析

    介绍 前面一章说了AbstractApplicationContext中的refresh方法中的invokeBeanFactoryPostProcessors.主要是调用BeanFactoryPostProcessor.其中也有获取bean的过程,就是beanFactory.getBean的方法.这一章就说下getBean这个方法.由于spring中获取bean的方法比较复杂,涉及到的流程也非常多,这一章就先说下整个大体的流程.其中的细节会在后面也会慢慢说. 源码 直接看源码吧 @Overrid

  • Spring Security源码解析之权限访问控制是如何做到的

    〇.前文回顾 在实战篇<话说Spring Security权限管理(源码详解)>我们学习了Spring Security强大的访问控制能力,只需要进行寥寥几行的配置就能做到权限的控制,本篇来看看它到底是如何做到的. 一.再聊过滤器链 源码篇中反复提到,请求进来需要经过的是一堆过滤器形成的过滤器链,走完过滤器链未抛出异常则可以继续访问后台接口资源,而最后一个过滤器就是来判断请求是否有权限继续访问后台资源,如果没有则会将拒绝访问的异常往上向异常过滤器抛,异常过滤器会对异常进行翻译,然后响应给客户端

随机推荐