文章目录
参考链接:
spring特点与好处
1 优势
Spring是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。
1.1 特点
-
方便解耦,简化开发
通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
-
AOP编程的支持
通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
-
声明事物的支持
在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。 -
方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。 -
方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。 -
降低Java EE API的使用难度
Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。 -
Java 源码是经典学习范例
Spring的源码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。
1.2 优点
总结起来,Spring有如下优点:
1. 低侵入式设计,代码污染极低
2. 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere
3. Spring的DI机制降低了业务对象替换的复杂性,降低组件之间的耦合度,不需要硬编码来组合各个组件
4. Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用
5. Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问
6. Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
2 使用Spring管理Bean
Spring的核心容器就是一个大工厂,所有的对象,也就是所有的Bean(包括数据源等)都是Spring核心容器管理的对象。只要是一个Java类,Spring就可以把它当作Bean来管理。
2.1 依赖:A对象需要调用B对象的方法。
如果xml文件中写了这样的bean:
<bean id="xiaoming" class="com.yangling.domain.Person">
<property name="axe" ref="axe"></property>
<!--value指定基本类型、包装类型、String等类型-->
<!--ref指定其他的Bean-->
<!--如果是有参构造函数,使用constructor-arg标签,constructor-arg标签有一个type属性-->
<!--例如 type="int"。同样的property标签也有这个type属性-->
</bean>
则以反射的方式调用该类的无参数构造方法:
String strid = XXX;
String classname = XXX;
Class clazz = Class.forName(classname);
Object obj = clazz.newInstance();
container.put(strid, obj); // 代表Spring容器
// 接下来是property标签:
String name = ""; // property的name
String ref =""; // property的ref
String setterName = "set"+name.subString(0,1).toUpperCase()+name.subString(1); // 生成将要调用的setter方法名
Object param = container.get(ref); // 容器中已经有的另一个Bean,当作传入给setter的参数
Method setter = clazz.getMethod(setterName, param.getClass()); // Class clazz = Class.forName(classname);取得的
setter.invoke(obj, param);
2.2 应用上下文:ApplicationContext是Spring容器中最常使用的接口。有两个实现类:
- ClassPathXmlApplicationContext :类加载路径总是不变的,所以通常使用本实现类。
- FileSystemXmlApplicationContext
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
Person p = applicationContext .getBean("xiaoming", Person.class);
// getBean有多种重载,如果不指定requiredType(也就是Person.class),那么返回值是Object类型
2.3 依赖注入等价于控制反转(描述角度不同)
调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受。调用者无需 new(或者通过工厂来获取被依赖对象),只需要被动接受Spring容器为调用者的成员变量赋值。
2.4 Spring容器
Spring容器最基本的接口是BeanFactory,负责配置、创建、管理Bean、Bean之间的依赖关系。它还有一个子接口ApplicationContext,功能更为强大。
ApplicationContext的额外功能;
1) 国际化(MessageSource)
2) 访问资源,如URL和文件(ResourceLoader)
3) 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
4) 消息发送、响应机制(ApplicationEventPublisher)
5) AOP(拦截器)
当系统创建ApplicationContext容器的时候,会默认初始化所有的单例Bean,此时表明系统初期会有较大的开销。而一旦容器初始化完成,程序后面获取单例对象时就会有不错的性能。而BeanFactory就不会预先初始化Bean,只在程序需要Bean的时候才初始化。
2.5 作用域
单例Bean:默认的Bean。scope="prototype"会改为多例。当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例;
参考 spring bean的单例和多例的使用场景和在单例bean中注入多例
每次通过容器的getBean()获取prototype作用域的Bean的时候,都将产生一个新的Bean实例并返回给程序,在这种情况下,容器仅仅使用new关键字来创建Bean,一旦创建成功,容器就不会跟踪实例、维护实例的状态。
request和session:如果不使用Spring MVC作为MVC框架,则无需额外配置。否则必须在Web应用的web.xml文件中增加Listener配置(将HTTP请求对象绑定到为该请求对象提供服务的线程上),这才能使得request和session作用域的Bean能在后面的调用链中被访问到。
2.6 嵌套Bean
如果某个Bean A所依赖的Bean B不想要被容器直接访问,则使用嵌套Bean。
把Bean B配置成property 或者constructor-arg 的子元素,此时Bean B仅作为setter和构造器的参数而存在:
<bean id="A" class="com.bean.Chinese"> <!--Bean A-->
<property name="axe">
<bean class="com.bean.SteelAxe"/> <!--Bean B-->
</property>
</bean>
提高了内聚性,但是降低了灵活性。只有在完全无需容器管理Bean B的时候,才考虑使用嵌套。
2.7 Spring Bean 和 Java Bean
- Spring容器对Bean没有特殊要求。功能更复杂,用法更丰富。Bean的生命周期由Spring管理。
- JavaBean要求必须为每个属性提供setter和getter。通常作为DTO数据传输对象,用来封装值对象,在各层之间传递数据。不接受任何容器来管理生命周期。
3 Java配置类的常用注解
配置类经常是为了给XML配置文件减肥。
- @Configure 用于修饰一个Java配置类。
- @Bean 用于修饰一个方法,将方法的返回值定义成一个Bean
- @ Value 用于修饰一个Field,为该Field配置一个值,相当于配置一个变量
- @Import 向当前配置类中导入其他的配置类
一旦使用Java配置类来管理容器中的Bean及其依赖关系,创建Spring容器时需要用这种方法:
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
ac.register(Another.class); // 添加其他的Java配置类