Spring框架学习

一、Spring的组件

在这里插入图片描述
可以看到核心组件有bean,core,context和spel我们在使用其制作项目时,也应导入相应的jar包

二、何为IOC?

(1) IOC,控制反转,英文全称为Inversion of Controller,其作用就是将设计好了的对象交给了spring容器借由工厂模式来创建和管理,简化了代码,降低程序的耦合度。

(2)beanDefinition – 承载bean的属性
beanFactory – 生成bean

(3)Spring加载bean的过程

首先,我们先了解一下javabean的加载方式
java对象的加载过程:
我们写一个类,通过类加载器ClassLoader,加载出一个Class类型的对象,通过字节码在JVM
在内存堆中new出一个对象,该对象的属性方法依照加载出来的Class对象。

而Spring中bean的加载流程如下:
首先对于一个实体类或者相关配置,通过类加载器Classloader,加载出一个Class类型的对象,然后解析注册生成BeanDefinition(里面包括beanName,scope等属性),之后BeanDefinition中定义的属性和值将存储在beanDefinitionMap中,根据BeanFactoryPostProcessor做处理然后遍历Map,进行相关检查,之后进行对象创建,属性注入,在初始化方法前查看是否有BeanPostProcessor,若有,执行相关前后处理或者AOP处理,最终将该类创建好后放入singletonObjects。当程序使用getbean时从中获取。

(4)IOC容器启动(调用AbstractApplicationContext的fresh方法)时,做了什么事?
1.加载配置
2.生成BeanFactory
3.解析注解,注册bean
4.生成单例bean(非懒加载)
具体步骤如下:
1.调用AbstractApplicationContext的fresh方法
2.创建beanFactory
3.依靠beanFactory来get bean
(具体调用了AbstractBeanFactory的getBean方法
AbstractBeanFactory的doGetBean方法)
4.bean先从单例对象池singletonObjects中获取,有,直接返回,没有去处理创建逻辑
(具体方法Object sharedInstance = getSingleton(beanName) 😉
5.创建bean
(具体方法doCreateBean)
6.通过反射生成bean
7.填充属性,注入依赖
8.初始化bean

补:
bean生命周期:创建(newInstance )填充属性,注入依赖,初始化,销毁(单例bean)
具体如下:
Bean 的生命周期
1.Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化

2.Bean实例化后对将Bean的引入和值注入到Bean的属性中

3.如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法

4.如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入

5.如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。

6.如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。

7.如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用

8.如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。

9.此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。

10.如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。
在这里插入图片描述

三、何为DI?

DI,依赖注入,英文名为Dependency Injection,其作用即提供在xml配置文档中,对构造函数或者对象进行关联和传递参数

四、什么是AOP?

AOP,全称Aspect Oriented Programming,即面向切面编程,是面向对象编程的延续,利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各个部分的耦合度降低,提高开发的效率。AOP底层实现是Java动态代理和CGLIB代理 (取决于被代理对象是否为接口)而动态代理会交给BeanPostProcessors做处理
相关术语:
1.Joinpoint:连接点,所谓连接点是指被拦截到的点,在spring中,指的是方法
2.pointcut:切入点,指要对哪些来连接点进行定义
3.Advice:通知,指拦截到jointpoint之后要做的事,即在切入点上做的增强
4.Introduction:引介,是一种特殊的通知,能在不修改代码的前提下,在运行期为类动态地添加一些方法
5.Target:目标对象,代理的目标对象
6.Waving:织入,是指把增强应用到目标对象来创建新的代理对象的过程
7.AOP代理:AOP框架创建的对象,代理就是目标对象的增强

补:为什么jdk动态代理只能代理实现了接口的目标对象?

因为Java中不支持多继承,而JDK的动态代理在创建代理对象时,默认让代理对象继承了Proxy类,而代理对象需要通过继承或者接口来获取被代理对象,被代理对象一般是类,又不能继承(已经继承了Proxy),所以只能通过被代理对象的接口来获取代理对象。所以JDK只能通过接口去实现动态代理。而CGLIB动态代理则不会默认继承任何类,而让代理类继承目标类,所以不用接口也可以。

补:如何改正Spring中的乱码问题?

Spring中post请求出现乱码,配置过滤器,设置utf-8
Spring中get请求出现乱码,修改Tomcat中service.xml中的Connector,加URIEncoding=utf-8

五、BeanPostProcessor和BeanFactoryPostProcessor区别

BeanPostProcessor:
在初始化方法前后增强,此时bean已经实例化。
BeanFactoryPostProcessor:
Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。此时bean尚未实例化。

六、BeanFactory和FactoryBean的区别

BeanFactory:
定义了IOC容器的基本形式,并提供了IOC容器应遵守的最基本的接口。Spring中的BeanFactory
有:ApplicationContext,ClassPathXmlApplication,AnnoationConfigApplication
其源码如下:

public interface BeanFactory {
	String FACTORY_BEAN_PREFIX = "&";

	Object getBean(String var1) throws BeansException;

	<T> T getBean(String var1, Class<T> var2) throws BeansException;

	<T> T getBean(Class<T> var1) throws BeansException;

	Object getBean(String var1, Object... var2) throws BeansException;

	<T> T getBean(Class<T> var1, Object... var2) throws BeansException;

	boolean containsBean(String var1);

	boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;

	boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String var1, ResolvableType var2)
			throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String var1, Class<?> var2)
			throws NoSuchBeanDefinitionException;

	Class<?> getType(String var1) throws NoSuchBeanDefinitionException;

	String[] getAliases(String var1);
}

FactoryBean:
一般情况下,Spring通过反射机制利用的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。例如以下使用:
如果使用传统方式配置下面Car的时,Car的每个属性分别对应一个元素标签。

package  com.zhb.factorybean;  
    public   class  Car  {  
        private   int maxSpeed ;  
        private  String brand ;  
        private   double price ;  
        public   int  getMaxSpeed ()   {  
            return   this . maxSpeed ;  
        }  
        public   void  setMaxSpeed ( int  maxSpeed )   {  
            this . maxSpeed  = maxSpeed;  
        }  
        public  String getBrand ()   {  
            return   this . brand ;  
        }  
        public   void  setBrand ( String brand )   {  
            this . brand  = brand;  
        }  
        public   double  getPrice ()   {  
            return   this . price ;  
        }  
        public   void  setPrice ( double  price )   {  
            this . price  = price;  
       }  
}

如果用FactoryBean的方式实现就灵活点,下例通过逗号分割符的方式一次性的为Car的所有属性指定配置值:

package  com.zhb.factorybean;  
import  org.springframework.beans.factory.FactoryBean;  
public   class  CarFactoryBean  implements  FactoryBean<Car>  {  
    private  String carInfo ;  
    public  Car getObject ()   throws  Exception  {  
        Car car =  new  Car () ;  
        String []  infos =  carInfo .split ( "," ) ;  
        car.setBrand ( infos [ 0 ]) ;  
        car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ;  
        car.setPrice ( Double. valueOf ( infos [ 2 ])) ;  
        return  car;  
    }  
    public  Class<Car> getObjectType ()   {  
        return  Car. class ;  
    }  
    public   boolean  isSingleton ()   {  
        return   false ;  
    }  
    public  String getCarInfo ()   {  
        return   this . carInfo ;  
    }  
  
    // 接受逗号分割符设置属性信息  
    public   void  setCarInfo ( String carInfo )   {  
        this . carInfo  = carInfo;  
    }  
}

有了这个CarFactoryBean后,就可以在配置文件中使用下面这种自定义的配置方式配置CarBean了:

<bean id="car"class="com.zhb.factorybean.CarFactoryBean" P:carInfo="奔驰,500,660000"/>

当调用getBean(“car”)时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法CarFactoryBean#getObject()方法返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值