Spring基本知识点

1.什么是BeanDefinition?

BeanDefinition表示Bean定义,Spring根据BeanDefinition来创建对象

BeanDefinition重要属性:

  • beanClass:表示一个类的类型,Spring在创建过程中会根据此属性来实例化得到对象

  • scope:表示一个bean的作用域,例如:scope为singleton表示该bean是一个单例bean,scope为prototype表示该bean是一个原型bean

  • isLazy:表示一个bean需不需要懒加载,懒加载的bean会在第一次getBean的时候生成bean,非懒加载的bean会在spring启动过程中直接生成好,原型bean的islazy属性不起作用(懒加载是针对单例bean的)

  • dependsOn:表示一个bean在创建之前所依赖的其它bean,在一个bean创建之前,它所依赖的这些bean的先全部创建好

  • primary:表示一个bean是主bean,在Spring中一个类型可以有多个bean对象,在进行依赖注入时,如果根据类型找到了多个bean,此时会判断这些bean中是否存在一个主bean,如果存在,则直接将这个bean主入给属性

  • initMethodName:表示一个bean的初始化方法,一个bean的生命周期过程中有一个步骤加初始化,Spring会在这个步骤中调用bean的初始化方法,初始化逻辑由程序员自己控制,表示程序员可以自定义逻辑对bean进行加工

    在工作中使用到的@Component、@Bean、这些都会解析为BeanDefinition

2.什么是BeanFactory?

BeanFactory是一种“Spring容器”,BeanFactory翻译过来是Bean工厂,它可以用来创建Bean、获取Bean,BeanFactory是Spring中非常核心的组件

BeanDefination、BeanFactory、Bean对象三者之间的关系:

BeanFactory将利用BeanDefinition来生成Bean对象,BeanDefinition相当于BeanFactory的原材料,Bean对象就相当于BeanFactory生产出来的产品

BeanFactory的核心子接口和实现类:

  • ListableBeanFactory
  • ConfigurableBeanFactory
  • AutowireCapableBeanFactory
  • AbstractBeanFactory
  • DefaultListableBeanFactory:支持单例Bean、支持Bean别名、支持父子BeanFactory、支持Bean类型转换、支持Bean后置处理、支持FactoryBean、支持自动装配等等

3.什么是Bean生命周期?

Bean生命周期描述的是Spring中一个Bean创建过程和销毁过程中所经历的步骤,其中Bean创建过程是重点,程序员可以利用Bean生命周期机制对Bean进行自定义加工

Bean生命周期核心步骤:

  • BeanDefinition,Bean定义:BeanDefinition表示Bean定义,它定义了某个Bean的类型,Spring就是利用BeanDefinition来创建Bean的,比如需要利用BeanDefinition中beanClass属性确定Bean的类型,从而实例化出对象
  • 构造方法推断选出一个构造方法:一个Bean中有多个构造方法,Spring来推断到底使用哪个构造方法
  • 实例化,构造方法反射得到对象:通过构造方法反射得到一个实例化对象,在Spring中,可以通过BeanPostProcessor机制对实例化进行干预
  • 属性填充,给属性进行自动填充:实例化所得到的对象,是不完整的对象,不完整的意思是该对象中的某些属性还没有进行属性填充,也就是Spring还没有自动给某些属性赋值,属性填充就是我们通常所说的自动注入、依赖注入
  • 初始化,对其他属性进行赋值校验:在一个对象属性填充之后,Spring提供的初始化机制,程序员可以利用初始化机制对Bean进行自定义加工,比如可以利用initializingBean接口来对Bean中其它属性进行赋值,或对Bean中的某些属性进行校验
  • 初始化后AOP生成代理对象:初始化后Bean创建生命周期最后一个步骤,我们常说AOP机制,就是在这个步骤中通过BeanPostProcessor机制实现的,初始化后得到的对象才是真正的Bean对象

4.@Autowired是什么?

@Autowired表示某个属性是否需要进行依赖注入,就可以写在属性和方法上。注解中required属性默认为true,表示如果没有对象可以注入给属性则跑异常。

  • @Autowired加在某个属性上,Spring在进行Bean生命周期的过程中,在属性填充这一步,会基于实例化出来的对象,对该对象中加了@Autowire的属性自动给属性赋值。Spring会根据属性的类型去Spring容器中找出所有Bean对象,如果找出来多个,在根据属性的名字从多个中确定一个。如果required属性为true,并且根据属性信息找不到对象,则直接抛异常。(主要步骤,完整的底层筛选逻辑更多,不仅只有这两步)
  • @Autowired注解写在某个方法上时,Spring在Bean生命周期的属性填充阶段,会根据方法的参数类型、参数名字从Spring容器中找到对象当作方法入参,自动反射调用该方法
  • @Autowired注解加在构造方法上时,Spring会在推断构造方法阶段,选择该构造方法来进行实例化,在反射调用构造方法之前,会先根据构造方法参数类型、参数名从Spring容器中找到Bean对象,当做构造方法入参

5.@Resource是什么?

@Resource注解与@Autowired类似,也是用来依赖注入的,@Resource是Java层面所提供的注解,@Autowired是Spring所提供的注解,它们依赖注入的底层逻辑也不同。

@Resource注解中有一个属性、针对name属性是否有值,@Resource的依赖注入底层流程是不同的。@Resource如果name属性有值,那么Spring会直接根据所指定的name值去Spring容器中找Bean对象,如果找到了则成功,没找到则报错。@Resource中name属性没有值,则先判断属性名字在Spring容器中是否存在Bean对象,如果存在,则成功找到Bean对象进行注入,如果不存在,则根据属性类型去Spring容器中找Bean对象,找到一个则进行注入

6.@Value是什么

@Value注解和@Resource、@Autowired类似,也是用来对属性进行依赖注入的,只不过@value是用来从Properties文件中来获取值的,并且@Value可以解析SpEL(Spring表达式)

@Value(“str_aaa”):会把字符串str_aaa进行注入,如果属性类型不是String,并且无法进行类型转化则报错

@Value(" s t r a a a " ) : 将 会 把 {str_aaa}"):将会把 straaa"){}中的字符串当做key,从Properties文件中找出对应的value赋值给属性,如果没找到,则会把${str_aaa}当作值注入给属性

@Value("#{strAaa}"):会将#{}中的字符串当作Spring表达式进行解析,Spring会把strAaa当作beanName,并从Spring容器中找对应bean,如果找到则进行属性注入,没找到则报错

7.FactoryBean是什么?

FactoryBean是Spring所提供的一种灵活的创建Bean的方式,可以通过实现FactoryBean接口的getObject()方法来返回一个对象,这个对象就是Bean对象。FactoryBean对象本身也是一个Bean,同时相当于一个小型工厂,可以生产出另外的Bean。BeanFactory是一个Spring容器,是一个大型工厂,可以生产出各种各样的Bean。

  • Object getObject():返回的是Bean对象
  • boolean isSingleton(): 返回的是否是单例Bean对象
  • Class getObjectType():返回的是Bean对象的类型
@Service("testService")
public class TestService implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new User();
    }

    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

上述代码实际生成可两个Bean对象:

1.beanName为"testService",bean对象为getObject()方法返回的User对象

2.beanName为"&testService",bean对象为TestService类的实例对象

8.ApplicationContext是什么

ApplicationContext是比BeanFactory更加强大的Spring容器,它既可以创建bean、获取bean,还支持国际化、事件广播、获取资源等BeanFactory不具备的功能。

ApplicationContext所继承的接口

  • EnvironmentCapable:ApplicationContext继承了这个接口,表示拥有了获取环境变量的功能,可以通过ApplicationContext获取操作系统环境变量和JVM环境变量

  • ListableBeanFactory: ApplicationContext继承了这个接口,就拥有了获取所有beanNames、判断某个beanName是否存在beanDefinition对象、统计BeanDefinition个数、获取某个类型对应的有beanNames等功能

  • HierarchicalBeanFactory:ApplicationContext继承了这个接口,就拥有了获取父类BeanFactory、判断某个name是否存在bean对象的功能

  • MessageSource:ApplicationContext继承了这个接口,就拥有了国际化功能,比如可以直接利用MessageSource对象获取某个国际化资源(比如不同国家所对应的字符)

  • ApplicationEventPublisher:ApplicationContext继承了这个接口,就拥有了事件发布的功能,可以发布事件,这是ApplicationContext相对于BeanFactory比较突出、常用的功能。

  • ResourcePatternResolver:ApplicationContext继承了这个接口,就拥有了加载并获取资源的功能,这里的资源可以是文件,图片等某个URL资源。

9.BeanPostProcessor是什么

BeanPostProcessor是Spring所提供的一种机制,可以利用该机制对Bean进行定制化加工,在Spring底层源码实现中,也广泛的用到了该机制,BeanPostProcessor通常也叫做Bean后置处理器。

BeanPostProcessor在Spring中是一个接口,我们定义一个后置处理器就是提供一个类实现该接口,在Spring中还存在一些接口继承了BeanPostProcessor,这些子接口是在BeanPostProcessor的基础上增加了一些其它功能。

BeanPostProcessor中的方法:

public interface BeanPostProcessor {
  
 		//初始化前方法,表示可以利用这个方法来对Bean在初始化前进行自定义加工
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
		
    //初始化后方法,表示可以利用这个方法来对Bean在初始化后进行自定义加工
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

InstantiationAwareBeanPostProcessor中的方法

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
	
  //实例化前
   @Nullable
   default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
      return null;
   }
	
  //实例化后
   default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
      return true;
   }
	
  //属性注入后
   @Nullable
   default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
         throws BeansException {

      return null;
   }

   @Deprecated
   @Nullable
   default PropertyValues postProcessPropertyValues(
         PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

      return pvs;
   }

}

10.AOP是什么?

AOP是面向切面编程,是一种非常适合在无需修改业务代码的前提下,对某个或某些业务增加统一的功能,比如日志记录、权限控制、事务管理等,能很好的使得代码解耦,提高开发效率

  • Advice:Advice可以理解为通知、建议,在Spring中通过定义Advice来定义代理逻辑
  • Pointcut:Pointcut是切点,表示Advice对应的代理逻辑应用在哪个类、哪个方法上
  • Advisor:等于Advice+pointcut,表示代理逻辑和切点的一个整体,程序员可以通过定义或封装一个Advisor,来定义切点和代理逻辑
  • Weaving:表示织入,将Advice代理逻辑在源代码级别嵌入到切点的过程,就叫做织入
  • Target:Target表示目标对象,也就是被代理对象,在AOp生成代理对象中会持有目标对象
  • Join Point:Join Point表示连接点,在Spring AOP中,就是方法的执行点

AOP的工作原理:

1.Spring生成bean对象时,先实例化出来一个对象,也就是target对象

2.再对target对象进行属性填充

3.在初始化后步骤中,会判断target对象有没有对应的切面

4.如果有切面,就表示当前对象需要进行AOP

5.通过Cglib或JDK动态代理机制生成一个代理对象,作为最终的bean对象

6.代理对象有一个target属性指向了target对象

11.什么是Spring?

Spring是一个生态:可以构建java应用所需要的一切基础设施

通常Spring指的是Spring Framework

核心解释:

  • Spring是一个轻量级的开源框架
  • Spring是为了解决企业级应用开发的业务逻辑层和其它各层,对象和对象直接耦合的问题
  • Spring是一个IOC和AOP的容器框架
    • IOC:控制反转
    • AOP:面向切面编程
    • 容器:包含并管理应用对象的生命周期

12.Spring IOC的实现机制是什么?

简单工厂+反射

13.IOC和DI的区别是什么?

IOC:控制反转思想,解决耦合问题

DI:依赖注入,是实现IOC的一个过程

14.BeanFactory和FactoryBean有什么区别?

BeanFactory是一个工厂,也就是一个容器,是来管理和生产bean的;FactoryBean是一个bean,所以也是由BeanFactory来管理的,不过FactoryBean不是一个普通的Bean,它会表现出工厂模式的样子,BeanFactory里面的getObject()就是用来获取FactoryBean产生的对象,所以在BeanFactory中使用“&”来得到FactoryBean本身,用来区分通过容器获取FactoryBean产生的对象还是获取FactoryBean本身

15.Spring IOC容器的加载过程?

1.实例化一个ApplicationContext对象

2.调用bean工厂后置处理器完成扫描

3.循环解析扫描出来的类信息

4.实例化一个BeanDefinition对象来存储解析出来的信息

5.把实例化好的beanDefinition对象put到beanDefinitionMap当中缓存起来,以便后面实例化bean

6.再次调用其它bean工厂后置处理器

7.当然Spring还会干很多事情,比如国际化,比如注册BeanPostProcessor等等,如果我们只关心如何实例化一个bean的话,那么这一步就是spring调用finishBeanFactoryInitialization方法来实例化单例bean,实例化之前spring要做验证,需要遍历所有扫描出来的类,一次判断这个bean是否是Lazy,是否prototype,是否abstract等等

8.如果验证完成spring在实例化一个bean之前需要推断构造方法,因为spring实例化对象是通过构造方法反射,故而需要知道用哪个构造方法

9.推断完构造方法之后spring调用构造方法反射实例化一个对象;注意是对象,这个时候对象已经实例化出来了,但是并不是一个完整的bean,最简单的体现是这个时候实例化出来的对象属性是没有注入,所以不是一个完整的bean

10.spring处理合并完成后的beanDefinition

11.判断需要是否完成属性注入

12.如果需要完成属性注入,则开始注入属性

13.判断bean的类型回调Aware接口

14.调用生命周期回调方法

15.如果需要代理则完成代理

16.put到单例池-bean完成-存在spring容器中

16.Spring IOC有哪些扩展点?

1.BeanDefinitionRegistryPostProcessor Bean定义后置处理器

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    /**
     * IOC加载时注册BeanDefinition时会调用
     */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClass(Object.class);
        registry.registerBeanDefinition("object",rootBeanDefinition);
    }

    /**
     * 在注册beanDefinition时调用
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        
    }
}

2.加载BeanPostProcessor实现类:在Bean的生命周期会调用9次Bean的后置处理器

3.初始化阶段调用XXXAware接口的SetXXXAware方法

public class MyClass implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {
    
    private BeanFactory beanFactory;
    
    private String beanName;
    
    private ApplicationContext applicationContext;
    
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public void setBeanName(String name) { 
        this.beanName = name;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext =applicationContext;
    }
}

4.执行BeanPostProcessor实现类的postProcessorBeforeInitialization方法

5.执行InitializingBean实现类的afterPropertiesSet方法

public class MyClass2 implements InitializingBean {
    
    @Override
    public void afterPropertiesSet() throws Exception {
        //初始化阶段调用
    }
}

6.执行bean的init-method属性指定的初始化方法

public class MyClass2 {

    @PostConstruct
    public void init(){
        //执行bean的init-method属性指定的初始化方法
    }

}

7.执行BeanPostProcessor实现类的postProcessAfterInitialization方法

8.初始化完成

9.关闭容器,执行Disposible实现类的destory

10.执行bean的destory-method属性制定的初始化方法

public class MyClass2 {

    @PreDestroy
    public void destroy(){
        
    }
}

17. 配置Bean有哪几种方式

1.xml

2.@Component(@Controller、@Service、@Repository) 前提需要配置 利用反射调用构造方法

3.javaConfig:@Bean (可以自己控制实例化过程,配合@Configuration)

4.@Imort。//TODO

18.Bean有那几种作用域

singleton:每一个Spring IoC容器都拥有唯一的一个实例对象

prototype:一个Bean定义,任意多个对象

request:一个HTTP请求会产生一个Bean对象,也就是说,每一个HTTP请求都有自己的Bean实例。只在基于web的Spring ApplicationContext中可用

session:限定一个Bean的作用域为HTTPsession的生命周期。同样,只有基于web的Spring ApplicationContext才能使用

application:限定一个Bean的作用域为全局HTTPSession的生命周期。通常用于门户网站场景,同样,只有基于web的Spring ApplicationContext可用

19.Spring的bean是线程安全的吗?

单例bean的不安全的情况:

如果在类中声明成员变量(有状态bean),并且有读写操作,就会线程不安全

Spring如何处理线程并发问题:

  • 将bean的作用域变为多例
  • 将成员变量放在ThreadLocal
  • 方法或者代码块上加上同步锁,影响性能

20.Spring构造方法推断

所有构造方法不加@Autowired注解的情况下:

1.有一个构造方法,直接用该构造方法

2.有多个构造方法,如果多个构造方法中有无参构造方法,用无参构造方法;如果没有无参构造方法,报错

只有一个构造方法加@Autowired注解的情况下,使用该构造方法

有多个构造方法加@Autowired注解的情况下,有无参构造方法用无参构造方法,无无参构造方法报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值