什么是spring?
是一个轻量级Java开发框架,用于简化java开发。主要核心为Ioc和Aop。通过Ioc实现对象耦合关系的管理,并实现反转,保证组件之间的松耦合,有AOP进增强服务
优点:
方便解耦、简化开发--spring本身是一个大工厂,将所有对象的创建和依赖关系的维护交给spring容器管理
支持面向切面编程----对程序进行权限拦截、应用监控
声明式事务支持---通过xml配置文件完成事务的管理
方便测试、集成优秀框架
缺点: 依赖反射影响性能、学习时间长
具有设计模式:
工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
单例模式:Bean默认为单例模式。
代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener(应用监听器)。
SpringIOC?
IOC:控制反转,就是有spring容器去创建和管理对象,依赖注入是IOC的一种具体实现。
但我认为它是一种设计思想,不是一种技术。通过spring的xml文件描述bean与bean之间的依赖关系,通过解析xml文件将内容存储到map集合中,通过反射机制完成对象的创建并对其进行依赖注入
构造注入:对象在构造完成之后,即已进入就绪状态,可以马上使用。依赖对象多,依赖不当有可能出现循环依赖
setter注入:灵活性高,便于修改依赖对象。依赖对象需要进行非空检查,对象无法在构造完成后处于马上就绪状态
SpringAOP?
AOP:面向切面编程,将于业务无关,对多个对象的公关行为和逻辑产生影响的模块进行抽取并且封装叫做切面。用于减少系统负担、降低模块耦合性、提高系统的维护性。多用于权限、日志事务处理。
AOP实现方式:动态代理和静态代理
动态代理:在aop框架中不修改原有代码的基础上,在每次程序运行的内存中产生一个aop对象,这个对象包含原有目标对象的所有方法,并且在特定的切点做增强处理,最后回调原对象的方法
静态代理:aop框架在编译期间生成一个aop代理类,通过静态织入的方式到java字节码文件中,然后运行得到增强的aop代理对象
动态代理的分类
JDK动态代理:只能对实现了接口的类生成代理,而不能针对类;
CGLIB:是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承);
JDK动态代理:利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
CGLiB动态代理:利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
spring的bean的生命周期?
容器启动,springIOC定义bean并且实例化bean,实例化完成后对其进行属性赋值
检查Aware接口:是否实现BeanNameAware接口、实现将bean的名称传递给setBeanName方法
如果实现BeanFactory接口,那么将beanFactory对象交给setBeanFactory方法
如果实现ApplicationConextAware接口,那么应用的上下文传入给SetApplicationConext方法进行调用
如果Bean实现了IntialzingBean接口,spring将调用它的afterPropertiesSet()接口方法
如果在xml文件中通过<bean>标签的init-method元素指定了初始化方法,那么该方法将被调用;
此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;
若bean实现了DisposableBean接口,spring将调用它的distroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用;
Bean的创建:当spring容器启动,加载bean.xml文件,调用getbean方法
Bean的销毁:当容器关闭或者停止服务
BeanFactory和ApplicationContext的联系和区别
Bean Factory是Spring里面最低层的接口,提供简单的容器功能,实例化对象和拿对象的功能
ApplicationContext应用上下文,继承BeanFactory接口,它是Spring的一个更高级容器,提供更多功能,例如:国际化、访问资源、载入(有继承关系的上下文),使得每一个上下文都专注于一个特定的层次,消息发送、响应机制、aop
BeanFactory启动时不会去实例化bean,而是从容器中拿到Bean才会去实例化
ApplicationContext启动时所有的bean已经实例化完成了,还可以用来配置bean的延迟实例化
什么是spring的bean?
是spring应用的主干java对象,他们被容器初始化、装配、管理。
@Autowired和@Resource之间的区别
@AutoWired可以注入:构成函数、成员变量、setter方法
@Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。
Spring如何解决循环依赖问题
循环依赖:是一个BeanA中依赖BeanB,然后BeanB中也依赖BeanA,当然也可以是更多Bean之间的循环依赖,A依赖B,B依赖C,C依赖A这种
依赖问题:构造注入、setter注入
一级缓存:单例对象的缓存(存放就绪状态的bean)表示自定义的初始化完成
二级缓存:提前曝光的单例对象的缓存(用来存放早期曝光的Bean)表示还未进行初始化,实现了Aware接口方法没有回调
三级缓存:单例对象工厂的缓存(在ioc容器中,刚被创建的Bean)
三个缓存之间流转的顺序(循环引用)
通过反射机制创建bean实例,单例bean,并且在ioc容器运行bean之间相互循环引用,放入3级缓存中
当发生循环引用,从3级缓存中取出bean对应的ObjectFactory实例,调用getObject方法,来获取早期曝光的bean,在3级缓存中移除,保存到二级缓存中
当初始化完成,在保存到一级缓存,从二级缓存以及三级缓存中移除
三个缓存之间流转的顺序(无循环引用)
通过反射机制创建bean实例,单例bean,并且在ioc容器运行bean之间相互循环引用,放入3级缓存中
当bean初始化完成,生命周期方法执行完毕,保存到一级缓存,移除二级和三级缓存