Spring笔记

Spring

概述

分层的JavaSE/EE (一栈式) 轻量级开源框架。

  • 表现层:Spring MVC
  • 持久层:JdbcTemplate、ORM框架整合
  • 业务层:IoC、AOP、事务控制

核心思想

  • IoC(Inverse of Control 反转控制): 将对象创建权利交给Spring工厂进行管理
  • AOP(Aspect Oriented Programming 面向切面编程),基于动态代理的功能增强方式

优点

  • 方便解耦,简化开发

    • Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理
  • AOP编程的支持

    • Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
  • 声明式事务的支持

    • 通过配置就可以完成对事务的管理,无需手动编程
  • 方便程序的测试

    • Spring对Junit4支持,可以通过注解方便的测试Spring程序
  • 方便集成各种优秀框架

    • Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持
  • 降低JavaEE API的使用难度

    • Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

配置

环境搭建

  • 核心包
    • beans
    • core
    • context
    • expression
  • 日志包
    • apache common-logging
    • log4j

核心配置文件

  • 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"
         xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="" class=""/>
    </beans>
装配bean的四种方式
  • 无参构造(最常用)

    <bean id="beanid" class="bean"/>
  • 静态工厂(某些框架初始化使用)

    <bean id="beanid" class="factory" factory-method=""/> 可以在实例化的方法中书写业务
  • 实例工厂(某些框架初始化使用)

    <bean id="factoryid" class="factory"/>
    <bean id="beanid" factory-bean="factoryid" factory-method=""/>
  • FactoryBean方式(spring底层使用)

    public class MyFactoryBean implements FactoryBean<Bean>{
    public Object getObject()throws Exception{
      return new Bean();
    }
    }
    <bean id="beanid" class="factory"/>
  • BeanFactory和FactoryBean的区别

    • BeanFactory(ApplicationContext):是一个工厂(其实是构建了一个spring上下文的环境,容器),用来管理和获取Bean对象
    • FactoryBean:是一个Bean生成工具,是用来获取一种类型对象的Bean,是构造Bean实例的一种方式

IOC

通过工厂获取bean

  • 读取配置文件,获取工厂
    • 配置文件在src目录下
    • ApplicationContext context=new ClassPathXmlApplicationContext(“applicationContext.xml”)
    • 配置文件在WEB-INF目录下
    • new FileSystemXmlApplicationContext(“applicationContext.xml”)
  • 生成bean
    • context.getBean(“id”);与xml中注册的id或name一致
    • context.getBean(Bean.class)如果注册了多个Bean,spring找不到唯一对象报错

DI依赖注入

  • 在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中
  • 对Bean对象的属性赋值
依赖注入的方式
  • 接口注入(spring不支持)

  • 构造器参数注入

    • 配置文件
    <bean name="" class="">
    <constructor-arg name="" index="0" type="java.lang.Double" ref="" value=""/>定位属性可以联合使用 赋值属性只能存在一个
    <constructor-arg name="">
        <value>value</value>
      </constructor-arg> 
    </bean>
    • 配置文件中参数个数必须与构造方法一致
  • setter方法注入

    • 配置文件
    <bean name="" class="">
    <property name="" ref=""/>
    <property name="">
    <ref bean=""/>
    </property>
    </bean>
    • 必须有无参构造
    • 相应属性有setter方法
    • 属性名可以与标签中name不一致,但setter方法必须与标签一致
p名称空间的使用
  • 引入名称空间

    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
         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.xsd">
  • 将子标签转化为p属性

    <bean name="" class="" p:username="" p:car-ref=""/>

ApplicationContext

  • 父接口BeanFactory

Bean的作用域

  • singleton

    • 在一个spring容器中,对象只有一个实例。默认值
     Spring使用ThreadLocal解决线程安全问题 
     对于实体bean一般通过方法参数的的形式传递(参数是局部变量),所以多线程之间不会有影响
     有的地方对于有状态的bean直接使用prototype原型模式来进行解决
     对于使用bean的地方可以通过new的方式来创建
  • prototype
    • 在一个spring容器中,存在多个实例,每次getBean 返回一个新的实例
  • request
    • 每次请求创建一个实例,仅适用于WebApplicationContext环境
  • session
    • 每个Session创建一个实例,仅适用于WebApplicationContext环境
  • globalSession
    • 用于Porlet环境,仅适用于WebApplicationContext环境

Bean的生命周期

  • 通过 init-method属性 指定初始化后的调用方法

  • 通过 destroy-method属性 指定销毁对象前的方法

     <bean name="" scope="singleton" class="" init-method="" destroy-method=""/>
    • 销毁方法执行的条件
      • singleton类型的bean才可以手动销毁
      • 手动关闭容器
    (ClassPathXmlApplicationContext)context.close();
  • singleton第一次getBean时工厂实例化并加载所有配置,工厂关闭时销毁

  • prototype每次getBean时实例化,destroy方法无法由工厂调用

Bean类的初始化

  • init方法
    • 完全解耦,init方法专门书写初始化代码,构造器只用来构造对象
  • 直接赋值
    • 耦合性最强,一般用于给默认值
  • 在构造器中初始化
    • 使用有参构造来初始化,new的时候直接初始化,但有点耦合

spEL表达式

基本语法#{}
  • 引用Bean(具体对象) #{beanid}
    * 可以替代ref属性
  • 引用Bean的属性#{beanId.属性}
  • 调用Bean的方法{beanId.方法(参数)}
集合类型注入
  • list集合

    <bean name="" class="">
    <property name="list">
         <list>
        <value>aa</value>
        <value>bb</value>
         </list>
    </property>
    </bean>
  • set集合

    <bean name="" class="">
    <property name="list">
         <set>
        <value>aa</value>
        <value>bb</value>
         </set>
    </property>
    </bean>
  • map集合

    <bean name="" class="">
    <property name="list">
         <set>
        <entry key="" key-ref="" value="" value-ref=""/>valuevalue-ref不能同时存在
        <entry key="">bb</value>
         </set>
    </property>
    </bean>
  • properties集合

    <property name="properties"> Properties集合只支持字符串属性键值对
     <props>
       <prop key="c">cc</prop>
       <prop key="d">dd</prop>
     </props>
    </property>

配置文件分开管理

  • 主配置文件中包含其他的配置文件

    <import resource="applicationContext2.xml"/>
  • 工厂创建的时候加载多个配置文件

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                      "applicationContext.xml","applicationContext2.xml");

注解开发

基本流程

  • 搭建环境配置

    • spring-aop的jar包

    • 约束

    xmlns:context="http://www.springframework.org/schema/context"  
    schemalocation:"http://www.springframework.org/schema.context
    http://www.springframework.org/schema.context/spring-context.xsd"

  • 配置注解扫描

    <context:component-scan   base-package="com.xxx.spring.test"/>
  • 在类上添加注解

常用注解

  • @Component
    • @Controller
    • @Service
    • @Repository
  • 属性注入(可以不提供set方法)
    • @Value注入普通类型
    • @Autowired
    • 默认按类型装配
    • @Qualifier按名称注入
    • @Resource
    • 相当于AutoWired和Qualifier同时使用
  • bean作用范围注解
    • @Scope
    • singleton
    • prototype
  • 生命周期
    • @PostConstruct表示init方法
    • @PreDestroy表示destroy方法

JUNIT测试

  • 导包

    spring-test.jar
    
    spring-test-3.2.0.RELEASE.jar
  • @RunWith(SpringJunit4ClassRunner.class)

  • @ContextConfiguration(locations=”classpath:applicationContext.xml”)

  • 在测试类中注入 测试对象

    • @AutoWired
  • 最后的test类应该用注解配置并进行ioc注入,xml配置不生效

AOP开发

概述

  • 横向抽取机制,取代了传统纵向继承体系重复性代码的编写方式(性能监视、事务管理、安全检查、缓存,日志记录等)。
  • 从父类继承的方法也可以加强
术语
  • joinpoint连接点
  • pointcut切入点
  • advice通知
  • introduction引介
  • target
  • weaving织入
    • spring采用动态代理织入
    • AspectJ采用编译期织入和类装载期织入
  • proxy
  • aspect

实现原理

  • JDK动态代理
    • 接口代理,spring优先使用
  • cglib动态代理
    • 生成子类代理

基本流程

  • ​ 环境搭建

    导入包
    spring-aop-4.2.4.RELEASE.jar
    com.springsource.org.aopalliance-1.0.0.jar
    
    spring-aspects-4.2.4.RELEASE.jar
    com.springsource.org.aspectj.weaver-1.0.0.jar
    
    引入约束
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xsi:schemalocation="http://www.springframework.org/schema/aop"
    http://www.springframework.org/schema/aop/spring-aop.xsd
  • 配置切面类

    • 编写切面类
    • 编写配置文件
    <bean name="aspectid"  class="" />
    
    <aop:config name="properties"> 
    配置切入点
    <aop:pointcut expression="execution()" id="pointcut"/> 全局切入点,针对所有切面生效
    execution配置:[public] * cn.xxx.spring.dao.*.* (..) 修饰符 返回值 包名 类名 方法名 参数
    配置切面
    <aop:aspect ref="aspectid">
        <aop:pointcut expression="execution()" id="pointcut"/> 仅针对当前生效
      <aop:before method="before" pointcut-ref="pointcut"/>
    </aop:aspect>
    </aop:config>
  • 切入点语法

    • bean(bean Id/bean name)
    • execution(<访问修饰符>?<返回类型>空格<方法全名>(<参数>)<异常>?)
    • within(包.类)
    • within(cn.itcast.spring..*) 增强spring包和子包所有bean“所有方法 ”
    • this(完整类型)/target(完整类型)
    • this(cn.itcast.spring.a_jdkproxy.CustomerServiceImpl) 增强类型所有方法(对代理对象有效)
    • target(cn.itcast.spring.a_jdkproxy.CustomerServiceImpl) 增强类型所有方法(对源对象有效)
    • 通配符
    • *:匹配任何数量字符;
    • ..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数
    • +:匹配指定类型的子类型;仅能作为后缀放在类型模式后边
    • 多个切入点表达式用||连接

通知类型

  • 前置通知

    <aop:before method="before" pointcut-ref="pointcut"/> 如果写pointcut,值为execution表达式
  • 后置通知

    public void after(Jointpoint joinpoint,Object object){object是invoke的返回值
    //...
    }
    
    <aop:after-returning method="after" after-returning="object" pointcut-ref="pointcut"/>
  • 环绕通知

    public Object after(ProceedingJointpoint joinpoint) throws Throwable{ //object是invoke的返回值
    //...
    Object obj joinpoint.proceed();
    //...
    return obj;
    }
    
    <aop:around method="around" pointcut-ref="pointcut"/>
  • 异常通知

    public void afterThrowing(Jointpoint joinpoint,Throwable ex){object是invoke的返回值
    //...
    }
    
    <aop:after throwing="after" throwing="ex" pointcut-ref="pointcut"/>
  • 最终通知

    public void afterThrowing(Jointpoint joinpoint){object是invoke的返回值
    //...
    }
    
    <aop:after throwing="after" throwing="ex" pointcut-ref="pointcut"/>

注解aop开发

  • 编写pojo类作为增强类

    • 添加@Aspect注解
    • 交给spring管理
    • @Component(“myAspect”)
  • 在通知方法上添加

    • @before
    • @afterReturning
    • @after
    • @around
    • @afterThrowing
    • @declaredParents
  • 开启AepectJ注解自动代理

    <aop:aspectj-autoproxy/>
    自动扫描带有@aspect注解的bean,将其作为增强aop配置,相当于<aop:config>
    
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    调用cglib机制生成代理
  • 使用@pointcut定义切入点

    • aspect类中书写方法
    @pointcut("bean(*)")
    public void myAspect(){}
    • 具体方法上定义要使用的切入点
    @before(value="com.it.spring.Myaspect.myAspect()") //写方法的全路径,用于引入其他类中定义的切入点
    public void before(){}
    • 方法上直接定义切入点
    @before("bean(*)") //内部参数直接写表达式,该表达式仅针对当前方法生效
    public void before(){}
    
    @before("bean(*)||mypointcut()") //对多个切入点生效,mypointcut()应该是本类的方法
    public void before(){}

对dao层的aop

管理连接池

  • 内置连接池

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="username" value="root"/>
    <property name="password" value="123"/>
    <property name="url" value="jdbc:mysql:///crm"/>
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>
  • c3p0连接池

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="username" value="root"/>
    <property name="password" value="123"/>
    <property name="jdbcUrl" value="jdbc:mysql:///crm"/>
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    </bean>
  • 将连接池注入template

    <bean id="template" class="org.springframework.jdbc.coreJdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <bean id="accountDAO" class="test.AccountDAO">
    <property name="template" ref="template"/>
    </bean>
  • 引入外部属性文件

    <context:property-placeholder location="classpath:db.properties"> 
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
    <property name="driverClass" value="${jdbc.password}"/>
    </bean>
  • 继承DAOSupport

    public final void setDataSource(DataSource dataSource){
    if(..){
      this.jdbctemplate=createTemplate(dataSource);
      initTemplateConfig();
    }
    }
  • 编写配置文件,注入注入jdbcTemplate

    <bean id="accountDAO" class="test.AccountDAO">
    <property name="dataSource" ref="dataSource"/>
    </bean>

JDBC模板

update(String sql, Object... args)
queryForObject(String sql, Class<T> requiredType, Object... args) 
query(String sql, RowMapper<T> rowMapper, Object... args)

事务管理

事务管理器
  • 接口PlatformTransactionManager
  • 实现
    • DataSourceTransactionManager
    • HibernateTransactionManager
事务定义
  • 接口TransactionDefinition
  • 方法
    • getIsolationLevelt隔离级别
    • getPropagationBehavior传播行为
    • getTimeout超时时间
    • isReadOnly 只读
事务状态
  • 接口TransactionStatus
  • 方法
    • flush()
    • hasSavepoint()
    • isCompleted()
    • isNewTransaction()
    • isRollbackOnly()
    • setRollbackOnly()
编程式事务
  • TransactionTemplate
声明式事务
  • 使用XML或注解配置声明式事务
  • Spring的声明式事务通过AOP实现
配置文件方式
  • 引入约束

    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">
  • 配置对特定持久层框架使用的事务管理器

      <bean id="transactionManager" class="org.springframework.jdbc.dataSource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
      </bean>
    
       <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
      </bean>
      这是用来向切面类TransactionInterceptor注入的属性
  • 配置通知

    <bean id=”transactionInterceptor”  class=” org.springframework.transaction.interceptor.TransactionInterceptor”>不常用
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="transfer" isolation="DEFAULT" timeout="-1" rollback-for="" non-rollback-for=""/>
             <!-- transfer后的方法按照这一行的配置进行增强,其他的按照默认方式增强(默认每个操作为一个事务,相当于没增强)-->
      </tx:attributes>
    </tx:advice>
  • 配置切面

    <aop:config name="properties"> 
    <!--  配置切入点-->
    <aop:pointcut expression="execution()" id="pointcut"/> 
    <!--   配置切面-->
    
    <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/> 
    <!--  默认使用TransactionInterceptor的intercept方法
          相当于 <aop:aspect ref="aspectid"><aop:before method="before" pointcut-ref="pointcut"/></aop:aspect>-->
    </aop:config>
注解方式
  • 开启注解扫描

  • 配置注解驱动事务管理

    • 注册事务管理注解
    <tx annotation-drivern  transaction-manager="transactionManager"/>
    当注册的事务管理器idname为transactionManager 
    <tx annotation-drivern />
    • 配置对特定持久层框架使用的事务管理器
    <bean id="transactionManager" class="org.springframework.jdbc.dataSource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
    </bean>
  • 在需要管理事务的方法或者类上面 添加@Transactional 注解

    • 事务定义信息在注解中直接配置
  • 类上的@Transactional 注解为所有本类public方法包装事务

  • 方法上的@Transactional 注解覆盖本类上的@Transactional 注解

xml与注解的对比
  • XML方式 ,使用通配符集中式维护

    <tx:method name="transfer*" isolation="default" timeout="-1" rollback-for="" non-rollback-for=""/>
    <tx:method name="save*" isolation="default" timeout="-1" rollback-for="" non-rollback-for=""/>
    <tx:method name="update*" isolation="default" timeout="-1" rollback-for="" non-rollback-for=""/>
    <tx:method name="find*" isolation="default" timeout="-1" rollback-for="" non-rollback-for=""/>

事务传播行为

  • 使用一个事务
    • PROPAGATION_REQUIRED(默认值,如果当前没有事务则创建一个 事务)
    • PROPAGATION_SUPPORTS(使用当前事务,如果当前没有事务则不使用)
    • PROPAGATION_MANDATORY(使用当前事务,当前没有事务则抛异常)
  • 使用独立事务
    • PROPAGATION_REQUIRES_NEW(如果有新事务,挂起当前事务,开启新事务)
    • PROPAGATION_NOT_SUPPORTED(非事务方式运行,挂起当前事务)
    • PROPAGATION_NEVER(非事务方式运行,如果有当前事务抛异常)
  • 嵌套事务
    • PROPAGATION_NESTE
    • 当A执行之后,就会在这个位置设置一个保存点.如果B没有问题.执行通过.如果B出现异常,运行客户根据需求回滚

SSH的整合

环境搭建

  • jar包导入

    • struts2
    struts2-core-2.3.32.jar
    xwork-core-2.3.32.jar
    ognl-3.0.19.jar
    asm-3.3.jar
    asm-commons-3.3.jar
    asm-tree-3.3.jar
    commons-fileupload-1.3.2.jar
    commons-io-2.2.jar
    commons-lang3-3.2.jar
    freemarker-2.3.22.jar
    javassist-3.11.0.GA.jar
    • hibernate
    antlr-2.7.7.jar
    dom4j-1.6.1.jar
    geronimo-jta_1.1_spec-1.1.1.jar
    hibernate-commons-annotations-5.0.1.Final.jar
    hibernate-core-5.0.7.Final.jar
    hibernate-jpa-2.1-api-1.0.0.Final.jar
    jandex-2.0.0.Final.jar
    javassist-3.18.1-GA.jar已经导入
    jboss-logging-3.3.0.Final.jar
    • 日志包
    log4j-1.2.16.jar
    • 数据库驱动
    mysql-connector-java-5.1.42-bin.jar
    • 连接池
    c3p0-0.9.2.1.jar
    
    用spring全整合hibernate时不需要
    mchange-commons-java-0.2.3.4.jar
    hibernate-c3p0-5.0.7.Final.jar
    • spring
    核心包
    spring-core-3.2.0.RELEASE.jar
    spring-beans-3.2.0.RELEASE.jar
    spring-expression-3.0.5.RELEASE.jar
    spring-context-3.0.5.RELEASE.jar
    
    日志
    com.springsource.org.apache.commons.logging-1.1.1.jar
    log4j-1.2.16.jar已经导入
    
    aop实现
    spring-aop-4.2.4.RELEASE.jar
    spring-aspects-4.2.4.RELEASE.jar
    aop第三方
    com.springsource.org.aopalliance-1.0.0.jar
    com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
    
    事务与连接
    spring-jdbc-4.2.4.RELEASE.jar
    spring-tx-4.2.4.RELEASE.jar
    
    整合orm框架(hibernate)
    spring-orm-4.2.4.RELEASE.jar
    
    整合web资源
    spring-web-4.2.4.RELEASE.jar
    单元测试
    spring-test-4.2.4.RELEASE.jar
  • 配置文件

    hibernate.cfg.xml 
    log4j.properties 
    applicationContext.xml
    web.xml
    struts.xml 

整合web

  • 配置核心监听器

    • 启动tomcat时加载spring[配置文件
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
  • src下spring配置文件头

    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">

配置过滤器
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("menu.jsp...............");
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        ApplicationContext ac =
                WebApplicationContextUtils.getWebApplicationContext(req.getSession().getServletContext());
        CategoryService  categoryService = (CategoryService) ac.getBean("categoryService");
        List<Category> list = categoryService.findCategorysByCriteria(DetachedCriteria.forClass(Category.class));
        req.setAttribute("category_list", list);
        filterChain.doFilter(req, servletResponse);
    }

配置Action

  • 引入插件包

    struts2-spring-plugin.jar
    • 插件包下struts-plugin.xml生效
    • 覆盖default-struts.xml中常量
    <constant name="struts.objectFactory" value="spring">
    • 修改struts的对象工厂为 spring (StrutsSpringObjectFactory)
    • struts-core.jar 中default.properties中struts.objectFactory属性也被覆盖为spring
    • struts.objectFactory.spring.AutoWire被激活,默认按名称注入bean(可以手动修改为type等)
  • 创建action

    • Action由struts创建

    • StrutsSpringObjectFactory自行创建action

    • 不能被spring管理
    • 默认多实例

    • Action由spring创建

    • applicationContext.xml中配置bean类,类型为多例

    <bean id="bookAction" class="cn.itcast.ssh.web.action.BookAction" scope="prototype">
            <!-- 主动注入service -->
            <property name="bookService" ref="bookService"></property>
        </bean>
    • struts.xml中配置action的类名为bean的id,由spring的ioc容器提供action
    <action name="book_*" class="bookAction" method="{1}"></action>
    • applicationContext.xml中没有配置bean类,自行new一个action
  • action中注入service (spring与struts的整合)

    • 提供setter方法
    • Action由struts创建
    • StrutsSpringObjectFactoryt工厂根据名称和set方法自动装配service
    • Action由spring创建
    • 需要在bean类中配置property属性

配置service

  • service中注入dao
  • 配置事务管理
    • 配置事务管理器(必须)
    • 写操作需要配置事务管理器并在通知中将read-only属性配置为false
    • 读操作不受影响
    • 开启注解事务管理
    • 添加注解

配置DAO

注入SessionFactory
  • 继承HibernateDaoSupport

  • dao中注入SessionFactory(Spring与hibernate的整合)

    • 不带hibernate配置文件
    • spring中配置连接池(为了其他整合的框架使用)
    • 配置hibernate属性
    • 引入映射文件
    <!-- 加载外部属性文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 数据源 :c3p0-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 注意不同的数据源,属性不一定一样 -->
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
     <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
         <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Mysql5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
         </property>
    
          <property name="mappingResources">
            <list>
                <value>cn/it/spring/Book.hbm.xml</value>
                <value></value>
                <value></value>
                <value></value>
            </list>
         </property>
     </bean>
    • 带hibernate配置文件

    • 在spring配置文件中配置SessionFactory

    • 改写DAO,注入SessionFactory
    <!--1. 零障碍整合:Hibernate的核心配置文件独立 -->
     <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
            <!--注入hibernate.cfg.xml  
            在spring的所有配置中,只要属性名字带有location的单词,那么路径必须加上classpath:
            configLocation属性用来加载hibernate核心配置文件的位置-->
        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
     </bean>
  • 调用模板

    • getHibernateTemplate()
命名查询
  • HQL命名查询

    • 对Hql查询的优化
    • 将Hql语句从代码中剥离出来
    在hbm.xml中配置Hql语句
    <query name="Book.findBookByName">from Book where name like ?</query>
    
    getHibernateTemplate().findByNamedQuery(queryName, values);
  • SQL命名查询

    <sql-query name="selectEmpByJob">
    <return alias="e" class="entity.Emp"></return>   //此处不配置则无法完成自动封装
    select {e.*} from EMP e where e.job=:job
    </sql-query>
    
    <sql-query name="selectBlogsByContent">  
    <return alias="blog" class="cn.enjoylife.hibernate.bean.Blog" >  
    <return-property name="id" column="id"></return-property>  
    <return-property name="title" column="title"></return-property>  
    <return-property name="content" column="content"></return-property>  
    <return-property name="blogAuthorId" column="blogAuthorId"></return-property>  
    </return>  
    SELECT t.id "id",  
    t.title "title",  
    t.content "content",  
    t.BLOG_AUTHOR_ID "blogAuthorId"  
    FROM blog t  
    WHERE t.content LIKE :contentPattern  
    </sql-query>  
    
    <sql-query name="selectBlogsByContent">  
    <return-scalar column="id" type="integer"/>  
    <return-scalar column="title" type="string"/>  
    <return-scalar column="content" type="string"/>  
    SELECT t.id "id",  
    t.title "title",  
    t.content "content"  
    FROM blog t  
    WHERE t.content LIKE :contentPattern  
    </sql-query>  

配置延迟加载

  • 原因

    • 业务层查询数据返回后,session关闭, 表现层关联延迟数据,无法初始化
  • 解决

    • 配置为立即加载 lazy=false(占用资源)
    • Service方法返回前, 对延迟数据进行初始化(增加代码量)
    List<Employee> list = dao.findAll (); 
    for(Employee e : list ){
    Hibernate.initialize(e.getDepartment() );
    }
    • OpenSessionInView 机制
      • OpenSessionInViewFilter配置在struts2核心过滤器之前
      • session在web层创建,web层销毁
      • 副作用1:没有被事务管理的方法, OpenSessionInViewFilter 会将这些方法的事务变为 readOnly (配置事务的方法不受影响)
      • 副作用1:当页面超出缓冲区大小,渲染模板分次向response.getWriter中写数据,导致数据库连接被占用时间过长

        <filter>
        <filter-name>OpenSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
        </filter>
        <filter-mapping>
        <filter-name>OpenSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>过滤所有资源
        <url-pattern>*.action</url-pattern>过滤所有action
        <url-pattern>/customer_list.action</url-pattern>过滤指定action
        </filter-mapping>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值