一、简介
Spring是一个J2EE应用程序开源框架,是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,它是为了解决企业应用开发的复杂性而创建的。主要是针对JavaBean的生命周期进行管理的轻量级容器。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
二、两个概念
1:控制反转IOC\依赖注入DI
● 控制反转IOC(Inversion of Control):
控制反转意思就是说,当我们调用一个方法或者类时,不再有我们主动去创建这个类的对象,控制权交给别人(spring)。
● 依赖注入DI(Denpdency Injection):
依赖注入意思就是说,spring主动创建被调用类的对象,然后把这个对象注入到我们自己的类中,使得我们可以使用它。
2:AOP面向切面编程(Aspect-Oriented Programming)
AOP把一个方法看做是一个切面,在这个切面的前后或者周围,都可以设置其他的处理方法,进行一些特殊的处理。AOP的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。
三、7个模块
核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
四、必备jar包
org.springframework.aop (必须)
——Spring的面向切面编程,提供AOP(面向切面编程)的实现org.springframework.asm(必须)
——spring 2.5.6的时候需要asm jar包,spring3.0开始提供它自己独立的asm jar包org.springframework.aspects(必须)
——Spring提供的对AspectJ框架的整合org.springframework.beans(必须)
——所有应用都用到,包含访问配置文件,创建和管理bean等,是Spring IOC的基础实现。org.springframework.context.support(必须)
——Spring context的扩展支持,用于MVC方面org.springframework.context(必须)
——提供在基础IOC功能上的扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持。org.springframework.core(必须)
——Spring的核心工具包,其他包依赖此包org.springframework.expression(必须)
——Spring表达式语言org.springframework.instrument.tomcat
——Spring对tomcat连接池的集成org.springframework.instrument
——Spring对服务器的代理接口org.springframework.jdbc
——对JDBC 的简单封装org.springframework.jms
——为简化jms api的使用而做的简单封装org.springframework.orm
——整合第三方的orm实现,如hibernate,ibatis,jdo以及spring 的jpa实现org.springframework.oxm
——Spring对于object/xml映射的支持,可以让JAVA与XML之间来回切换org.springframework.test
——对JUNIT等测试框架的简单封装org.springframework.transaction
——为JDBC,HIBERNATE,JDO和JPA提供的一致性的声明式和简单编程式事务管理org.springframework.web.portlet
——Spring MVC的增强org.springframework.web.servlet
——对J2EE6.0 servlet3.0的支持org.springframework.web.struts
——整合struts框架的支持,可以更方便更容易的集成Struts框架。
spring jar包下载地址:
http://repo.spring.io/release/org/springframework/spring/依赖的Apache Commons Logging jar:
http://commons.apache.org/proper/commons-logging/download_logging.cgi
五、spring详细配置(此内容摘自:51cto.com)
下面,就上面的配置列举一个示例:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- 定义使用C3P0连接池的数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 指定连接数据库的JDBC驱动 --> <property name="driverClass"> <value>com.mysql.jdbc.Driver</value> </property> <!-- 连接数据库所用的URL --> <property name="jdbcUrl"> <value>jdbc:mysql://localhost:3306/eportal?useUnicode= true&characterEncoding=gbk</value> </property> <!-- 连接数据库的用户名 --> <property name="user"> <value>root</value> </property> <!-- 连接数据库的密码 --> <property name="password"> <value>root</value> </property> <!-- 设置数据库连接池的最大连接数 --> <property name="maxPoolSize"> <value>20</value> </property> <!-- 设置数据库连接池的最小连接数 --> <property name="minPoolSize"> <value>2</value> </property> <!-- 设置数据库连接池的初始化连接数 --> <property name="initialPoolSize"> <value>2</value> </property> <!-- 设置数据库连接池的连接的最大空闲时间,单位为秒 --> <property name="maxIdleTime"> <value>20</value> </property> </bean> <!-- 定义Hibernate的SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm. hibernate3.LocalSessionFactoryBean"> <!-- 依赖注入上面定义的数据源dataSource --> <property name="dataSource" ref="dataSource" /> <!-- 注册Hibernate的ORM映射文件 --> <property name="mappingResources"> <list> <value>com/eportal/ORM/News.hbm.xml</value> <value>com/eportal/ORM/Category.hbm.xml</value> <value>com/eportal/ORM/Memberlevel.hbm.xml</value> <value>com/eportal/ORM/Cart.hbm.xml</value> <value>com/eportal/ORM/Traffic.hbm.xml</value> <value>com/eportal/ORM/Newsrule.hbm.xml</value> <value>com/eportal/ORM/Merchandise.hbm.xml</value> <value>com/eportal/ORM/Admin.hbm.xml</value> <value>com/eportal/ORM/Orders.hbm.xml</value> <value>com/eportal/ORM/Cartselectedmer.hbm.xml</value> <value>com/eportal/ORM/Newscolumns.hbm.xml</value> <value>com/eportal/ORM/Member.hbm.xml</value> </list> </property> <!-- 设置Hibernate的相关属性 --> <property name="hibernateProperties"> <props> <!-- 设置Hibernate的数据库方言 --> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <!-- 设置Hibernate是否在控制台输出SQL语句,开发调试阶段通常设为true --> <prop key="show_sql">true</prop> <!-- 设置Hibernate一个提交批次中的最大SQL语句数 --> <prop key="hibernate.jdbc.batch_size">50</prop> <prop key="show_sql">50</prop> </props> </property> </bean> <!--定义Hibernate的事务管理器HibernateTransactionManager --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <!-- 依赖注入上面定义的sessionFactory --> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!--定义Spring的事务拦截器TransactionInterceptor --> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <!-- 依赖注入上面定义的事务管理器transactionManager --> <property name="transactionManager" ref="transactionManager" /> <!-- 定义需要进行事务拦截的方法及所采用的事务控制类型 --> <property name="transactionAttributes"> <props> <!-- 以browse、list、load、get及is开头的所有方法采用只读型事务控制类型 --> <prop key="browse*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="list*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="is*">PROPAGATION_REQUIRED,readOnly</prop> <!-- 所有方法均进行事务控制,如果当前没有事务,则新建一个事务 --> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <!-- 定义BeanNameAutoProxyCreatorf进行Spring的事务处理 --> <bean class="org.springframework.aop.framework.autoproxy. BeanNameAutoProxyCreator"> <!-- 针对指定的bean自动生成业务代理 --> <property name="beanNames"> <list> <value>adminService</value> <value>columnsService</value> <value>newsService</value> <value>crawlService</value> <value>memberLevelService</value> <value>memberService</value> <value>categoryService</value> <value>merService</value> <value>cartService</value> <value>ordersService</value> <value>trafficService</value> </list> </property> <!-- 这个属性为true时,表示被代理的是目标类本身而不是目标类的接口 --> <property name="proxyTargetClass"> <value>true</value> </property> <!-- 依赖注入上面定义的事务拦截器transactionInterceptor --> <property name="interceptorNames"> <list> <value>transactionInterceptor</value> </list> </property> </bean> <!-- 装配通用数据库访问类BaseDAOImpl --> <bean id="dao" class="com.eportal.DAO.BaseDAOImpl"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 部署系统用户管理业务逻辑组件AdminServiceImpl --> <bean id="adminService" class="com.eportal.service.AdminServiceImpl"> <property name="dao" ref="dao" /> </bean> <!-- 部署新闻栏目管理业务逻辑组件ColumnsServiceImpl --> <bean id="columnsService" class="com.eportal.service.ColumnsServiceImpl"> <property name="dao" ref="dao" /> </bean> <!-- 部署订单管理业务逻辑组件OrderServiceImpl --> <bean id="ordersService" class="com.eportal.service.OrderServiceImpl"> <property name="dao" ref="dao" /> </bean> <!-- 部署流量统计业务逻辑组件TrafficServiceImpl --> <bean id="trafficService" class="com.eportal.service.TrafficServiceImpl"> <property name="dao" ref="dao" /> </bean> <!-- 部署Struts 2负责系统用户管理的控制器AdminAction --> <bean id="adminAction" class="com.eportal.struts.action. AdminAction" scope="prototype"> <property name="service" ref="adminService" /> </bean> <!-- 部署Struts 2负责新闻栏目管理的控制器ColumnsAction --> <bean id="columnsAction" class="com.eportal.struts.action. ColumnsAction" scope="prototype"> <property name="service" ref="columnsService" /> </bean> <!-- 部署Struts 2负责新闻管理的控制器NewsAction --> <bean id="newsAction" class="com.eportal.struts.action. NewsAction" scope="prototype"> <property name="service" ref="newsService" /> <property name="columnsService" ref="columnsService" /> </bean> <!-- 部署Struts 2负责新闻采集规则管理的控制器CrawlAction --> <bean id="crawlAction" class="com.eportal.struts.action. CrawlAction" scope="prototype"> <property name="service" ref="crawlService" /> <property name="columnsService" ref="columnsService" /> </bean> </beans>
六、Spring注解
用注解来向Spring容器注册Bean。需要在applicationContext.xml中注册
<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>
1. @Service用于标注业务层组件(我们通常定义的service层就用这个)
2. @Controller用于标注控制层组件(如struts中的action)
3. @Repository用于标注数据访问组件,即DAO组件
4. @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service和 @Controller 其实这三个跟@Component 功能是等效的,把普通pojo实例化到spring容器中,相当于配置文件中的:
<bean id="" class=""/>
5. @Resource
6. @Autowired
7. @Qualifier
区别:
@Resource,它是javax.annotation.Resource; 这个包中,也就是说是javaEE中的,并不是spring中的。
而且@Resource("xxx") 是可以定义bean名称的,就是说我这个属性要用那个bean来赋值。
@Autowired,它是org.springframework.beans.factory.annotation.Autowired 是这个包中,它是spring的包。
而且它没有@Autowired("xxx"),那我要为这个bean定义名称怎么办这个时候可以用@Qualifier("xxx") 这个也是spring中的。这个xxx定义bean名称有什么用呢?我们回头看下刚才的代码。
小结:@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,如果发现找到多个bean,则,又按照byName方式比对,如果还有多个,则报出异常而@Resource默认按 byName自动注入罢了。其实spring注解,最常用的还是根据名称,根据类型啊,构造方法啊,用的非常少。所以在多个实现的时候我们定义好bean的名称就行,就不会错乱。
8. @Scope("下列值")
singleton:默认值,SpringIoc容器只会创建该Bean的唯一实例,所有的请求和引用都只使用这个实例
Property: 每次请求都创建一个实例
request: 在一次Http请求中,容器会返回该Bean的同一个实例,而对于不同的用户请求,会返回不同的实例。需要注意的是,该作用域仅在基于Web的Spring ApplicationContext情形下有效,以下的session和global Session也是如此
session:同上,唯一的区别是请求的作用域变为了session
global session:全局的HttpSession中,容器会返回该bean的同一个实例,典型为在是使用portlet context的时候有效(这个概念本人也不懂)
七、JAVA获取bean
//读取bean.xml中的内容 ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); //创建bean的引用对象 ClassName classname = ctx.getBean("beanId",classname.class);
注意:本文归作者所有,未经作者允许,不得转载