12、BeanFactory常用的实现类有哪些?
Bean工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从正真的应用代码中分离。常用的BeanFactory实现有DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。XMLBeanFactory,最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory,它根据XML文件中的定义加载beans。该容器从XML文件读取配置元数据并用它去创建一个完全配置的系统或应用。
Spring-DAO并非Spring的一个模块,它实际上是指示你写DAO操作、写好DAO操作的一些规范。因此,对于访问你的数据它既没有提供接口也没有提供实现更没有提供模板。在写一个DAO的时候,你应该使用@Repository对其进行注解,这样底层技术(JDBC,Hibernate,JPA,等等)的相关异常才能一致性地翻译为相应的DataAccessException子类。
Spring-JDBC提供了Jdbc模板类,它移除了连接代码以帮你专注于SQL查询和相关参数。Spring-JDBC还提供了一个JdbcDaoSupport,这样你可以对你的DAO进行扩展开发。它主要定义了两个属性:一个DataSource和一个JdbcTemplate,它们都可以用来实现DAO方法。JdbcDaoSupport还提供了一个将SQL异常转换为SpringDataAccessExceptions的异常翻译器。
Spring-ORM是一个囊括了很多持久层技术(JPA,JDO,Hibernate,iBatis)的总括模块。对于这些技术中的每一个,Spring都提供了集成类,这样每一种技术都能够在遵循Spring的配置原则下进行使用,并平稳地和Spring事务管理进行集成。
对于每一种技术,配置主要在于将一个DataSourcebean注入到某种SessionFactory或者EntityManagerFactory等bean中。纯JDBC不需要这样的一个集成类(JdbcTemplate除外),因为JDBC仅依赖于一个DataSource。
如果你计划使用一种ORM技术,比如JPA或者Hibernate,那么你就不需要Spring-JDBC模块了,你需要的是这个Spring-ORM模块。
Spring的WEB模块是构建在applicationcontext模块基础之上,提供一个适合web应用的上下文。这个模块也包括支持多种面向web的任务,如透明地处理多个文件上传请求和程序级请求参数的绑定到你的业务对象。它也有对JakartaStruts的支持。
Spring配置文件是个XML文件,这个文件包含了类信息,描述了如何配置它们,以及如何相互调用。
IOC控制反转:SpringIOC负责创建对象,管理对象。通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
IOC或依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。
FileSystemXmlApplicationContext:此容器从一个XML文件中加载beans的定义,XMLBean配置文件的全路径名必须提供给它的构造函数。
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
● BeanFactory
基础类型的IOC容器,提供完成的IOC服务支持。如果没有特殊指定,默认采用延迟初始化策略。相对来说,容器启动初期速度较快,所需资源有限。
● ApplicationContext
ApplicationContext是在BeanFactory的基础上构建,是相对比较高级的容器实现,除了BeanFactory的所有支持外,ApplicationContext还提供了事件发布、国际化支持等功能。ApplicationContext管理的对象,在容器启动后默认全部初始化并且绑定完成。
平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。
Spring提供了多种依赖注入的方式。
● set注入
● 构造器注入
● 静态工厂的方法注入
● 实例工厂的方法注入
Springbeans是那些形成Spring应用的主干的java对象。它们被SpringIOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中<bean/>的形式定义。Spring框架定义的beans都是单例beans。
一个SpringBean的定义包含容器必知的所有配置元数据,包括如何创建一个bean,它的生命周期详情及它的依赖。
当定义一个<bean>在Spring里,我们还能给这个bean声明一个作用域。它可以通过bean定义中的scope属性来定义。如,当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。另一方面,一个bean每次使用的时候必须返回同一个实例,这个bean的scope属性必须设为singleton。
Spring框架支持以下五种bean的作用域:
● singleton:bean在每个Springioc容器中只有一个实例。
● prototype:一个bean的定义可以有多个实例。
● request:每次http请求都会创建一个bean,该作用域仅在基于web的SpringApplicationContext情形下有效。
● session:在一个HTTPSession中,一个bean定义对应一个实例。该作用域仅在基于web的SpringApplicationContext情形下有效。
● global-session:在一个全局的HTTPSession中,一个bean定义对应一个实例。该作用域仅在基于web的SpringApplicationContext情形下有效。缺省的Springbean的作用域是Singleton。
Spring框架中的单例bean不是线程安全的。
当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean,为了定义innerbean,在Spring的基于XML的配置元数据中,可以在<property/>或<constructor-arg/>元素内使用<bean/>元素,内部bean通常是匿名的,它们的Scope一般是prototype。
Spring提供以下几种集合的配置元素:
● <list>类型用于注入一列值,允许有相同的值。
● <set>类型用于注入一组值,不允许有相同的值。
● <map>类型用于注入一组键值对,键和值都可以为任意类型。
● <props>类型用于注入一组键值对,键和值都只能为String类型。
无须在Spring配置文件中描述javaBean之间的依赖关系(如配置<property>、<constructor-arg>)。IOC容器会自动建立javabean之间的关联关系。
有五种自动装配的方式,可以用来指导Spring容器用自动装配方式来进行依赖注入。
● no:默认的方式是不进行自动装配,通过显式设置ref属性来进行装配。
● byName:通过参数名自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。
● byType::通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
● constructor:这个方式类似于byType,但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
● autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。
基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。以@Configuration注解为例,它用来标记类可以当做一个bean的定义,被SpringIOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。
注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置<context:annotation-config/>元素。
使用SpringJDBC框架,资源管理和错误处理的代价都会被减轻。所以开发者只需写statements和queries从数据存取数据,JDBC也可以在Spring框架提供的模板类的帮助下更有效地被使用,这个模板叫JdbcTemplate。JdbcTemplate类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。
在Spring中有两种方式访问Hibernate:
● 控制反转:HibernateTemplate和Callback。
● 继承HibernateDAOSupport提供一个AOP拦截器。
Spring支持以下ORM框架:
● Hibernate
● MyBatis
● JPA (Java Persistence API)
● TopLink
● JDO (Java Data Objects)
● OJB
AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此。这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
AOP技术恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为“Aspect”,即切面。所谓“切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。AOP核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。比如,一个日志模块可以被称作日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。
被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。
Spring切面可以应用五种类型的通知:
● before:前置通知,在一个方法执行前被调用。
● after:在方法执行之后调用的通知,无论方法执行是否成功。
● after-returning:仅当方法成功完成后执行的通知。
● after-throwing:在方法抛出异常退出时执行的通知。
● around:在方法执行之前和之后调用的通知。
切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。
被一个或者多个切面所通知的对象。它通常是一个代理对象。也指被通知(advised)对象。
代理是通知目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。
把切面(aspect)连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象,这样的行为叫做织入。织入可以在编译时,加载时,或运行时完成。