Spring是为企业应用的开发提供轻量级解决方法。包括:基于依赖注入的核心机制、基于AOP的声明式事务管理、与多种持久层技术的整合,以及优秀的Web MVC框架等。Spring贯穿表现层、业务层、持久层。
Spring优点:
使用Spring管理Bean,Spring把容器中的一切对象统称Bean。Spring对Bean没有任何要求,只要是一个java类就可以。所以一切对象都是Bean。Spring使用配置文件管理。
伪代码片段
//在xml中的配置
"" class ="">
"" value ="" ref ="">
//在Spring底层的实现
String id = "";
Class clazz = class.forName(classStr);
Object obj = clazz.newInstance();
container.put(id, obj);
String name = "";
String ref ="";
String classStr = "";
String setterName = "set"+name.subString(0,1).toUpperCase()+name.subString(1);
Object param = container.get(ref);
Method setter = clazz.getMethod(setterName, param.getClass());
setter.invoke(obj, param);
在Spring配置文件中配置Bean时,class属性的值必须是Bean实现类的完整类名,不能是接口,不能是抽象类,否则Spring无法使用发射创建类的实例。bean元素驱动Spring调用构造器,它的作用是默认驱动Spring在底层调用无参构造器创造对象,property驱动Spring执行setter方法,name属性值决定执行哪个setter方法(所以name的值跟java代码中的属性值相对应),而value或ref决定传入的参数值。这两步是先后执行的,中间几乎没有任何间隔。
ApplicationContext是Spring容器最常用接口,该接口有两个常用实现类:
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
Object obj = ctx.getBean("",xx.class);//使得程序不在使用new 调用构造器创建java对象,所有的java对象由Spring负责创建
也叫控制反转(IOC)或者依赖注入(DI),使用Spring框架之后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受。所以,叫控制反转。从容器的角度讲,Spring容器负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入它依赖的实例。
使用Spring框架之后的主要改变:
使用Spring IoC容器的三个基本要点:
依赖注入通常两种:
- 设值注入:使用成员变量的setter注入被依赖的对象
- 构造注入:使用构造器注入被依赖的对象。constructor-arg来代表构造参数
区别:设值注入先是通过无参构造器创建一个Bean实例,然后调用对应的setter方法注入依赖关系;构造注入是直接调用有参构造,当Bean实例创建完成后,已经完成了依赖注入。最后,建议采用以设值注入为主,构造注入为辅的策略。对于依赖关系无需变化的注入,尽量采用构造注入。
Spring有两个和新接口:
ApplicationContext是BeanFactory的子接口。Spring是生成Bean的工厂,并管理bean。
**区别**BeanFactory不会预初始化容器中的Bean,ApplicationContext会自动预初始化容器中的singleton Bean,也可以手动取消预初始化。所以,系统前期创建ApplicationContext时开销比较大,但一旦初始化完成,程序后面获取singleton Bean性能提升。一般推荐使用ApplicationContext。
ApplicationContext的事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener类接口,可以实现ApplicationContext的事件处理。
当通过Spring创建一个Bean实例,不仅可以完成bean实例化而且可以为Bean指定作用域。有5个作用域:
Spring的自动装配可通过autowire属性指定,该属性只对配置文件中所有的bean起作用,该属性可接受的值:
Spring容器对Bean没有特殊要求,甚至不要求该bean像标准的JavaBean必须为每个属性提供相应的setter和getter方法。Spring中的Bean是Java实例、Java组件;而传统的JavaBean是作为DTO(数据传输对象),用来封装值对象,在各层之间传递数据。
Spring中的Bean应满足几个原则:
传统的JavaBean和Spring中的Bean存在的区别:
实例工厂方法和静态工厂方法不同:配置静态工厂方法使用class指定静态工厂类,而配置实例工厂方法则使用factory-bean指定工厂实例。使用实例工厂方法时,配置bean实例的bean元素无需class属性,因为Spring容器不在直接实例化该Bean,Spring容器仅仅调用实例工厂的方法,工厂方法负责创建Bean实例。
调用静态工厂方法创建Bean与调用实例工厂方法创建Bean,相同之处:
- 都需要使用factory-method
- 工厂方法如果需要使用参数,都是用constructor-arg元素指定参数值
- 普通的设置注入,都是用property确定参数值
不同之处:
配置实例工厂方法创建Bean,必须使用factory-bean属性确定工厂Bean;而配置静态工厂方法创建Bean,则使用class元素确定静态工厂类。
将多个bean元素配置中的相同信息提取出来,集中成配置模板,这个bean并不是真正的bean,并且需要增加abstract=true,这就是抽象bean。抽象Bean不能被实例化,Spring容器不会创建抽象Bean实例,t它的价值在于被继承,所以可以不指定class属性。
子Bean可以通过parent属性指定其父的Bean,当子Bean所指的配置信息与父Bean不一致时将会覆盖父的bean。
前者是一般到特殊的细化,后者是实例与实例之间参数值的延续。前者是类与类之间的关系,后者是对象与对象的关系。区别:
这种工厂Bean必须实现FactoryBean接口,把工厂Bean部署在容器中之后,如果通过getBean获取它,容器返回的不是factoryBean实现类而是返回factoryBean的产品。
实现factoryBean接口的价值:Spring容器并不是简单的返回该实例而是返回该Bean实例的getObject方法的返回值,而该方法由开发者负责实现。
Spring可以管理singleton作用域的Bean的生命周期,可以精确的知道这个Bean何时被创建、何时被初始化完成、容器何时准备销毁该Bean实例。
对于Prototype作用域的Spring仅负责创建,当容器创建了Bean之后,完全交给客户端管理,容器不在跟踪其生命周期。
对于singleton作用域的,Spring可以管理实例化结束之后和销毁之前的行为,主要有两个时机:
Spring的本质就是通过XML配置来执行Java代码,因此几乎可以把所有的Java代码放到Spring配置文件中管理。
Spring IoC容器的作用:将原来的java代码管理的耦合关系,提取到xml中进行管理,从而降低了各组件之间的耦合,提高了系统的可维护性。