Spring知识点
一、 专业术语
1. 侵入式设计
引入框架,对现有的类的结构有影响,即需要实现或继承某些特定类。如:Struts框架
2. 非侵入式设计
引入框架,对现有的类结构没有影响。如:Hibernate、Spring
3. 控制反转(IoC)
控制反转(Inversion on Control 、IoC):把对象的创建交给外部容器完成。
4. 依赖注入(DI)
依赖注入(dependency injection):处理对象间的依赖关系
5. IoC和DI的区别
控制反转:解决对象创建的问题【对象创建交给其他类】
依赖注入:解决类与类紧耦合的问题。
例如,类A依赖于类B,常规的做法是在A中直接创建B的对象,然后再调用B对象的方法;控制反转就是将创建B对象的实例化交给第三方实现;然后再创建类B的操作接口I,并在A中创建接口I的对象,最后再由第三方将B的实例注入给A中的接口I的对象。这样实例化B类对象的控制权就由A交给了第三方,同时也解决了类A和类B紧耦合的问题。
6. AOP
面向切面编程(Aspect Oriented Programming)是软件编程思想发展到一定阶段的产物,是面向对象编程的有益补充。AOP一般适用于具有横切逻辑的场合,如访问控制、事务管理、性能监测等。面向切面编程简单地说就是在不改变源程序的基础上为代码段增加新的功能,对代码段进行增强处理。
7. 横切逻辑
在业务系统中,总有一些散落、渗透到系统各处且不得不处理的事情,这些穿插在既定业务中的公共操作就是所谓的横切逻辑,也称为切面。
8. 增强处理
在目标方法执行前后进行的操作或执行的功能就是增强处理。
9. 切点
可以插入增强处理的目标方法就是所谓的切点。
二、 Spring简介
Spring框架可以解决对象创建以及对象之间依赖关系的一个轻量级框架。Spring是一个全面的、企业应用开发一站式的解决方案,Spring贯穿表现层、业务层、持久层。但是Spring仍然可以和其他的框架无缝整合。
Spring特点
①、方便解耦,简化开发
通过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技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。
Spring可以通过配置文件管理实例,工厂模式也可以管理实例的初始化呀,为什么一定要使用Spring呢?
为什么不用工厂模式而使用IOC。其实本质上还是因为IOC是通过反射机制来实现的。当我们的需求出现变动时,工厂模式会需要进行相应的变化。但是IOC的反射机制允许我们不重新编译代码,因为它的对象都是动态生成的。
三、 Spring Jar包介绍
1. org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现
2. org.springframework.asm——spring3.0开始提供自己独立的asm jar包
3. org.springframework.aspects——Spring提供的对AspectJ框架的整合
4. org.springframework.beans——所有应用都用到,包含访问配置文件,创建和管理bean等。
5. org.springframework.context.support——Spring context的扩展支持,用于MVC方面
6. org.springframework.context——提供在基础IOC功能上的扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持。
7. org.springframework.core——Spring的核心工具包,其他包依赖此包
8. org.springframework.expression——Spring表达式语言
9. org.springframework.instrument.tomcat——Spring对tomcat连接池的集成
10. org.springframework.instrument——Spring对服务器的代理接口
11. org.springframework.jdbc——对JDBC 的简单封装
12. org.springframework.jms——为简化jms api的使用而做的简单封装
13. org.springframework.orm——整合第三方的orm实现,如hibernate,ibatis,jdo,jpa等
14. org.springframework.oxm——Spring对于object/xml映射的支持,可以让JAVA与XML来回切换
15. org.springframework.test——对JUNIT等测试框架的简单封装
16. org.springframework.transaction——为JDBC,HIBERNATE,JDO,JPA提供一致的声明式和编程式事务管理
17. org.springframework.web.portlet——Spring MVC的增强
18. org.springframework.web.servlet——对J2EE6.0 servlet3.0的支持
19. org.springframework.web.struts——整合对struts框架的支持,更方便更容易的集成Struts框架。
20. org.springframework.web——包含Web应用开发时,用到Spring框架时所需的核心类。
21. Org.springframework.web.mvc——包含SpringMVC应用开发时所需的核心类。
注意:core、beans、expression、context是Spring的核心jar包。使用Spring时必须导入commons-logging-*.jar包。
四、 applicatonContext.xml - bean配置详解
1. Spring相关的命名空间介绍
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
</beans>
2. bean相关的配置
<!-- IOC容器的配置: 要创建的所有的对象都配置在这里-->
<bean id="user" class="com.baidu.controller.User"
init-method="init_user" destroy-method="destroy_user" scope="singleton" lazy-init="false">
</bean>
<!-- 带参数构造器 -->
<bean id="user2" class="cn.itcast.b_create_obj.User">
<constructor-arg index="0" type="int" value="100"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="Jack"></constructor-arg>
</bean>
对象的创建(单例,多例)
scope="singleton" 单例(默认值)【service/dao/工具类建议使用】
scope="prototype" 多例【action/controller对象建议使用】
什么时候创建
scope="singleton" 启动时(容器初始化之前),就已经创建了bean,整个应用只有一个
scope="prototype" 用到对象时,才创建该对象。
是否延迟创建
lazy-init="false" 默认值,不延迟,在启动时就创建对象
lazy-init="true" 延迟初始化,在用到对象的时候才创建(只对单例有效)
创建对象之后,初始化/销毁
Init-method="init_user" 对应对象的init-user方法,在对象创建之后执行
destroy-method="destroy_user" 在调用容器(容器实现类)对象的destroy方法时候执行。
3. 对象依赖关系(DI相关)
依赖注入的几种实现方式:
- 通过构造函数
- 通过set方法给属性注入值
- 名称空间
- 自动装配(了解)
- 注解
<!-- 通过set方法进行注入 -->
<bean id="userService" class="com.baidu.c_property.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- 通过p命名空间进行注入其他bean -->
<bean id="userService" class="com.baidu.c_property.UserService" p:userDao-ref="userDao"></bean>
<!-- 通过p命名空间进行注入普通类型值 -->
<bean id="user" class="com.baidu.c_property.User" p:name="Jack0001"></bean>
<!-- 通过构造方法注入(构造方法包含1个参数) -->
<bean id="userService" class="com.baidu.spring.service.UserService">
<constructor-arg type="com.wskj.spring.dao.UserDao">
<ref bean="userDao1"/>
</constructor-arg>
</bean>
注意:通过p命名空间注入其他bean时,格式为:
p:属性名-ref="bean的id"
p:属性="属性值"
4. 自动装配
可以在bean节点上添加autowire属性实现依赖属性的自动注入。通过为bean设置autowire后,就不用再通过构造函数、set方法、p命名空间设置依赖关系了,这样就可以大大的简化配置的代码。可以在bean节点上单独为某个bean设置装配方式,也可以在beans节点上设置所有bean的默认装配方式(default-autowire)。
自动装配方式包括:
no:不适用自动装配
byType:根据类型进行装配
byName:根据bean名称进行装配
constructor:通过构造参数进行装配
五、 处理增强
1. 处理增强的类型
前置增强MethodBeforeAdvice
后置增强AfterReturningAdvice
环绕增强MethodInterceptor
抛出异常增强ThrowsAdvice
2. 实现增强的3种方式
通过接口实现增强
前置增强的接口为:MethodBeforeAdvice
后置增强的接口为:AfterReturningAdvice
环绕增强的接口为:MethodInterceptor
抛出异常增强的接口为:ThrowsAdvice
通过注解实现增强
通过Scheme配置实现增强
3. 通过接口实现增强
<aop:config>
<aop:pointcut expression="execution(public void *User())" id="addoptpointcut"/>
<aop:advisor advice-ref="logbefore" pointcut-ref="addoptpointcut" />
</aop:config>
<aop:config>
<aop:pointcut expression="execution(* spring_basic.UserService.*(..))" id="userServiceOptPointcut"/>
<!--
<aop:advisor advice-ref="exceptionAdvice" pointcut-ref="userServiceOptPointcut" />
-->
<aop:advisor advice-ref="logger" pointcut-ref="userServiceOptPointcut" />
</aop:config>
4. 通过注解实现增强
前置增强
@Before("execution(* service.*.*(..))")
后置增强
@AfterReturning(pointcut="execution(* service.*.*(..))", returning="result")
异常抛出增强
@AfterThrowing(pointcut="execution(* service.*.*(..))", throwing="ex")
环绕增强
@Around("execution(* service.*.*(..))")
注意:还需要在
applicationContext.xml
文件中添加如下配置
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
5. 通过Scheme配置实现增强
首先:添加普通的类,里面按要求编写方法
public class Logger {
public void before(JoinPoint jp){
}
public void after(JoinPoint jp, Object result){
}
public void aterThrowing(JoinPoint jp, Exception ex){
}
public Object aroundExecute(ProceedingJoinPoint pjp) throws Throwable{
}
}
其次:在
applicationContext.xml
中配置
aop-aspect
相关的配置
<aop:config>
<aop:pointcut expression="execution(* service.*.*(..))" id="optpointcut"/>
<aop:aspect ref="mylogger">
<aop:before method="before" pointcut-ref="optpc" />
<aop:after-returning method="after" returning="result" pointcut-ref="optpc" />
<aop:after-throwing method="aterThrowing" throwing="ex" pointcut-ref="optpc" />
<aop:around method="aroundExecute" pointcut-ref="optpointcut"/>
</aop:aspect>
</aop:config>
六、 拆分Spring配置文件
方式一:在web.xml文件中加载多个spring配置文件
<!-- spring监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,classpath:applicationContext-dao.xml,
classpath:applicationContext-service.xml,classpath:applicationContext-action.xml,
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
方式二:通配符方式加载多个spring配置文件
<!-- spring监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:applicationContext-*.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
方式三:使用import加载其他spring配置文件
<import resource="applicationContext-dao.xml" />
七、 SSH框架整合
1. 添加jar包
2. 在web.xml文件中添加spring和struts2相关的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ssh_template</display-name>
<!-- struts2的核心控制器 - 过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- spring监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:applicationContext-*.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- openSessionViewFilter解决懒加载问题 -->
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>*.do,*.action</url-pattern>
</filter-mapping>
<!-- spring解决中文乱码的过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置欢迎页面-->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
3. 配置struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 是否启用动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<!-- 配置strust2的对象工厂,使用Spring来管理对象的创建 -->
<constant name="struts.objectFactory" value="spring"/>
<!-- 让struts2始终先考虑spring的自动装箱 -->
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true" />
<package name="default" namespace="/" extends="struts-default">
<!--通配符配置action-->
<action name="*_*" class="com.tencent.qqzone.controller.{1}Action" method="{2}">
<result name="input" type="dispatcher">/pages/{1}/{2}.jsp</result>
<result name="list" type="dispatcher">/pages/{1}/{2}.jsp</result>
<result name="listAction" type="redirectAction">{1}_list</result>
</action>
</package>
</struts>
4. 配置applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
<!-- 加载属性文件 -->
<context:property-placeholder location="classpath:database.properties"/>
<!-- 创建dataSource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="driverClass" value="${jdbc.driverClassName}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<!-- 连接池中最大的连接数量 -->
<property name="maxPoolSize" value="40"></property>
<!-- 连接池中最少的连接数量 -->
<property name="minPoolSize" value="3"></property>
<!-- 连接池中初始的连接数量 -->
<property name="initialPoolSize" value="5"></property>
<property name="maxIdleTime" value="20"></property>
</bean>
<!-- sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- 设置数据源 -->
<property name="dataSource">
<ref bean="dataSource" />
</property>
<!-- 设置hibernate的配置文件 -->
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<!-- hibernate如果使用的注解方式,则需要添加下面的配置。用途:自动扫描注解方式配置的hibernate类文件 -->
<property name="packagesToScan">
<list>
<value>com.wskj.ssh.entity</value>
</list>
</property>
</bean>
<!-- 自动扫描包中的注解 -->
<context:component-scan base-package="com.tencent.qqzone"></context:component-scan>
<!-- 事务 -->
<!-- 1.配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 2.配置事务增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 定义事务传播属性 -->
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="new*" propagation="REQUIRED" />
<tx:method name="set*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="query*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="search*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 3.配置事务的切入点和增强 -->
<aop:config>
<aop:pointcut id="serviceOperation"
expression="execution(* com.tencent.qqzone.service..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
</aop:config>
</beans>
5. 配置hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置hibernate方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="jdbc.batch_size">20</property>
<property name="connection.autocommit">true</property>
<!-- 显示sql语句 -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- 编码,解决和数据库操作时的中文乱码问题 -->
<property name="connection.useUnicode">true</property>
<property name="connection.characterEncoding">UTF-8</property>
<!-- 在下面添加hibernate的实体映射文件 -->
<mapping resource="com/tencent/qqzone/pojo/LogCategory.hbm.xml" />
<mapping resource="com/tencent/qqzone/pojo/LogInfo.hbm.xml" />
</session-factory>
</hibernate-configuration>
6. 编写各个功能模块的相关代码,并配置action
。