zoukankan      html  css  js  c++  java
  • spring框架

    http://www.springsource.org/
    下载:http://repo.spring.io/release/org/springframework/spring
    或者到http://repo.spring.io->Artifacts->搜索spring-framework-4.x.x.RELEASE
    spring是一个设计层面的框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。

    ******************************************************************
    一:
    最少jar包:
    spring-beans-*.jar
    spring-context-*.jar
    spring-core-*.jar
    spring-expression-*.jar
    spring-aop-*.jar(4.0以上)
    commons-logging-*.jar(struts)


    自动提示:xml在schema中找

    配置xml(参考文档7.2)
    控制反转IOC:Inversion of control
    依赖注入DI:Dependency injection

    spring注入:
    set注入(重要)
    构造注入
    属性注入
    采用p:属性='值' or p:属性-ref=''方式注入(引入头7.4.2)
    <bean id='' class='' p:person="张嘎"/>

    <bean>中的name属性和id属性一样(name可以使用特殊字符(ey:/ &),可以重名,spring3.1开始id也支持特殊符号)
    直接属性值注入:value 属性 少用

    bean的生存范围:scope 属性 (文档) 默认singleton prototype(原型) request session...

    自动注入autowire:
    单个配:在<bean/>中配autowire(byName,byType:只能有1个类型匹配才行,如果两个同类型则报异常,对注解同样有效,无需@Autowired)
    配全局:在<beans/>中配default-autowire="byName",默认是no
    <bean/>里可以不配,因为默认为default

    bean生命周期:(只适用于singleton,prototype的生命周期容器不能控制)
    lazy-init(也分局部和全局)
    init-method="方法名"、destroy-method="方法名"
    要使destroy-method执行使用:ApplicationContext接口的实现类
    AbstractApplicationContext ctx = ...
    ctx.close();


    集合注入:查文档collections(7.4.2)
    List、Set、Map、Properties

    annotation:(4.0以上依赖aop包)
    1、配置xml的context头(参考文档7.9)
    <context:annotation-config/>(可选,被componet-scan集成)
    <context:component-scan base-package="com.cssl"/>(必须有)
    2、@Autowired默认是byType,如果找到多个类型匹配的,则按byName进行注入,如果还找不到对应bean,则报异常
    3、多个类型在set方法上或者方法的参数前加 @Qualifier("id的名称")
    4、@Resource(name="uDao") 默认是byName,没有则按byType,byType又有多个则异常
    name属性解析为bean的名字,而type属性则解析为bean的类型
    @Resource(name="usersDao",type=UsersDaoImpl.class)
    5、@Component, @Repository, @Service, @Controller效果一样,默认id为类名首字母小写
    6、@PostConstruct(init-method) and @PreDestroy(destroy-method)
    7、@Scope("prototype")
    8、@Value()注入固定值
    注解可以不写set方法直接注解到属性上

    ******************************************************************

    二、AOP
    A、AOP:Aspect Oriented Programming(见帮助文档11)
    引入aspectjweaver和aopalliance的包和spring-aop-x.jar 包
    另外转二进制包cglib(无接口的类被代理的情况下使用,spring3.2以上已经集成此包)

    JoinPoint 连接点
    PointCut 切入点(连接点集合)(切入点一般是定义在方法上,其实也可以在属性甚至类上)
    Aspect 切面(切面逻辑类)
    Advice 切面对于某个“连接点”所产生的动作,before、after、around(切入点建议)
    Target 被织入的对象(被一个或者多个切面所通知的对象)
    Weaving 织入

    aspectJ语法:11.2.3
    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
    modifiers-pattern:方法的操作权限
    ret-type-pattern:返回值
    declaring-type-pattern:方法所在的包
    name-pattern:方法名
    parm-pattern:参数名
    throws-pattern:异常

    public * com.cssl.service..*.*(..)
    within:spring自己的aop语法


    B、annotation配置:
    1、xml中必须加<aop:aspectj-autoproxy/>
    2、类上加@Aspect(切面逻辑)、@Component
    3、织入方法上写@Before(
    "execution(public void com.cssl.UserDao.save(com.cssl.Users))")
    4、也可以使用@AfterReturning|@After|@Around|@AfterThrowing
    5、@AfterReturning只有方法没有抛出异常的情况下执行,不管是否有返回值
    6、切面类上加@Order(1)决定哪个切面先执行

    注意:
    1、这里execution都是切入方法的语法
    @AfterThrowing要起作用必须是该切面上的方法抛出了异常(不能在切面方法中处理或调用切面方法的aspect类处理)

    2、写通用织入方法:(MyEclipse2014环境下不识别@Pointcut因为JDK7必须匹配aspectjweaver1.7.x)
    @Pointcut("execution(public * com.cssl..*.*(..))")
    public void cutAll(){};

    3、其他方法引入该织入点11.2.4
    @Before("cutAll()") || @Before("Logger.cutAll()")
    public void before(){}

    4、拦截含有参数的方法,并将参数值注入到当前方法的形参id,name中
    @Before("cutAll()&&args(id,name)")
    public void before(int id,String name)

    5、获取被切入方法的返回值
    @AfterReturning(pointcut="cutAll()",returning="result")
    public void afterReturn(JoinPoint jp,Object result)

    C、Spring提供的环绕处理类:
    1.)ProceedingJoinPoint proceed()
    public void around(ProceedingJoinPoint pjp) throws Throwable{
    ...
    //这里如果异常是自己处理了则@AfterThrowing捕获不到service方法抛出的异常
    pjp.proceed();
    ...
    }

    2.)JoinPoint
    @AfterReturning(pointcut="cut()",returning="result")
    public void afterMethod(JoinPoint jp,Object result){
    System.out.println(jp.getTarget());
    //result被代理方法返回值
    System.out.println("结束日志记录...:"+result);
    }


    D、xml配置:常用,特别是在切面逻辑是第三方提供的情况下
    <aop:config>...</aop:config>
    <aop:config>
    <aop:pointcut expression="execution(* com.cssl.service..*.add(..))" id="cutAll"/>
    <aop:aspect ref="logInfo">
    <aop:before method="before" pointcut="execution(public * com..*.*(int)) and args(id)" />
    <aop:after-returning method="afterReturn" pointcut-ref="cutAll" returning="result"/>
    </aop:aspect>
    </aop:config>
    等同下面
    <aop:config>
    <aop:aspect id="asp" ref="logInfo">
    <aop:before method="before" pointcut="execution(* com.cssl.service..*.add(..))"/>
    </aop:aspect>
    </aop:config>


    Spring的AOP实现:4种(没有AfterAdvice)

    MethodBeforeAdvice
    前置通知: 在某连接点JoinPoint之前执行的通知,但这个通知不能阻止连接点前的执行。

    AfterReturningAdvice
    返回后通知:在某连接点正常完成后执行的通知,不包括抛出异常的情况。

    MethodInterceptor
    环绕通知: 包围一个连接点的通知,类似Web中的Filter的doFilter方法。

    ThrowsAdvice
    异常通知: 在方法抛出异常退出时执行的通知。
    必须使用下面的方法签名:
    void afterThrowing([Method method, Object[] arguments, Object target,] Throwable ex)


    或者使用:(注意advice-ref引用的bean必须是Advice接口的实现类)
    <aop:config>
    <aop:pointcut expression="execution(public * com.cssl.service..*.*(..))" id="cut"/>
    <aop:advisor advice-ref="myBeforeAdvice" pointcut-ref="cut"/>
    </aop:config>

    Filter和Interceptor都是典型的面向切面编程


    *****************************************************************************************

    三、 Spring整合Hibernate4:Data Access(帮助文档17)

    导入hibernate包、spring的orm、jdbc、tx包


    使用属性配置文件:占位符的方式(${这里绝对不要多加空格}|不要使用byType byName自动注入)
    <bean id="ppc" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations" value="classpath:jdbc.properties"></property>
    </bean>
    也可以配置:
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 纯jdbc数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
    destroy-method="destroy">
    <property name="dataSource" ref="dataSource" />
    <!--
    <property name="annotatedClasses">
    <list>
    <value>com.cssl.pojo.User</value>
    <value>com.cssl.pojo.Log</value>
    </list>
    </property>

    注解
    <property name="packagesToScan">
    <list>
    <value>com.cssl.pojo</value>
    </list>
    </property>

    xml方式
    <property name="mappingDirectoryLocations">
    <list>
    <value>classpath:com/cssl/pojo/</value>
    </list>
    </property>
    -->

    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">
    org.hibernate.dialect.OracleDialect
    </prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.format_sql">true</prop>
    <prop key="hibernate.hbm2ddl.auto">update</prop>
    <!-- 没有整合spring的事务的时候使用Hibernate的线程管理thread -->
    <prop key="hibernate.current_session_context_class">thread</prop>
    <!-- 同thread 整合事务后spring可以不配置,如果要配置必须配置spring的currsession管理 -->
    <!--<prop key="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</prop>-->
    <!--整合spring事务的时候必须使用spring线程管理-->
    <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
    <!-- 和javaEE6冲突,解决beanValidate异常 -->
    <prop key="javax.persistence.validation.mode">none</prop>
    </props>
    </property>
    </bean>


    如果想仍然使用hibernate.cfg.xml:(不用再配置数据库连接,无法注入sessionFactory)
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="configLocations">
    <value>classpath:hibernate.cfg.xml</value>
    </property>
    </bean>

    自动搜索实体包(含子包):packagesToScan(annotation) mappingDirectoryLocations(xml)

    事务管理:默认catch到RuntimeException自动回滚:(对于手动处理的异常spring不再管理)
    (DataAccessException|HibernateException)

    <bean id="tx"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:advice id="txAdvice" transaction-manager="tx">
    <tx:attributes>
    <tx:method name="exists" read-only="true" />
    <tx:method name="add*" propagation="REQUIRED"/>
    <tx:method name="*" read-only="true"
    rollback-for="DataAccessException"
    no-rollback-for="NullPointerException,ClassCastException" />
    </tx:attributes>
    </tx:advice>

    <aop:config>
    <aop:pointcut id="bussinessService"
    expression="execution(public * com.cssl.service..*.*(..))" />
    <aop:advisor pointcut-ref="bussinessService"
    advice-ref="txAdvice" />
    </aop:config>

    readOnly:true|false 用于查询提高效率和防止意外插入、删除、更新操作
    timeout :事务超时时间,有的数据库事务不支持(mysql事务不支持、oracle注意驱动版本)

    bug:
    spring3.x整合hibernate4.3.0以上有:
    ClassNotFoundException
    org.hibernate.service.jta.platform.spi.JtaPlatform
    hibernate4.3这个文件的位置变了orghibernateengine ransactionjtaplatformspi导致spring引用出错

    使用spring4以上版本整合已修复此bug


    事务传播机制:文档17.5(了解)
    propagation(查spring_api:org.springframework.transaction.annotation.Propagation共7种,用Required)

    REQUIRED:业务方法需要在一个事务里运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务。

    REQUIRES_NEW:不管是否存在事务,该方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务挂起,新的事务被创建。

    NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。它是已经存在事务的一个真正的子事务,如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的savepoint。内部事务的回滚不会对外部事务造成影响。
    嵌套事务是外部事务的一部分, 只有外部事务结束后它才会被提交。

    使用NESTED必须
    1、在transactionManager中配置<property name="nestedTransactionAllowed" value="true"/>默认false
    2、java.sql.Savepoint 必须存在, 即 jdk 版本要 1.4+
    3、jdbc drive 必须支持 JDBC 3.0


    注意:
    同一个业务类里面,即使声明为 Propagation.REQUIRES_NEW也不会新启一个事务。必须调用另一个类的Propagation.REQUIRES_NEW方法才行,这样每个方法都是独立的事务,是互不影响的,外部事务的回滚不会影响内部事务的提交(不同于NESTED外部事务回滚内部事务也回滚),但如果内部事务回滚(抛出了异常),则相当外部事务的方法也抛出了异常(没有处理的情况)也将回滚!


    其他方式整合事务:
    annotation方式、拦截器方式、spring AOP方式。。。

    annotation事务:
    <tx:annotation-driven transaction-manager="txManager"/>
    方法前加@Trasactional:(默认Required)


    注意:Spring+Hibernate整合问题
    1、spring3.1开始支持hibernate4
    2、spring4.x整合hibernate4.x可以使用HibernateTemplate类或者HibernateDaoSupport(Template method设计模式)
    3、使用继承HibernateTemplate类或HibernateDaoSupport类的方式可以使用xml方式直接注入SessionFactory,
    但是如果想用annotation注入SessionFactory就需要重写setSessionFactory方法,然后在方法上用注解。
    继承HibernateTemplate可以重写,但继承HibernateDaoSupport不能重写因为该方法为final,所以必须写个其他方法在方法里调用setSessionFactory方法。
    4、spring3.x整合hibernate4.x不再支持HibernateTemplate及HibernateDaoSupport(Spring3.1以上的事务实现和hibernateTemplate相冲突)
    5、orm的hibernate3.x分xml和annotation的SessionFactory
    6、必须使用getCurrentSession(),current_session_context_class对应的class设置为org.springframework.orm.hibernate4.SpringSessionContext或者不指定,在此类中获取session时就已经把事务开启了。


    Spring测试框架:导入spring的test包
    分Junit3.8和Junit4
    (spring4.1.6只支持Junit4.9+hamcrest1.3)
    (spring4.3只支持Junit4.12+hamcrest1.3)
    数据库现场不受破坏,事务自动回滚(propagation="REQUIRED")
    @ContextConfiguation(locations="/applicationContext.xml")
    @Rollback(false) //默认为true
    //@TransactionConfiguration(过期)
    public class STest extends AbstractTransactionalJUnit4SpringContextTests {
    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private IService petService;

    @Test
    public void testPet(){
    this.petService.add();
    }
    }


    *****************************************************************************************

    四、spring整合struts2

    无缝整合:
    需要导入
    struts2中8个基本包和struts2-spring-plugin.jar、
    spring4中导入spring-web-x.x.x.RELEASE.jar (web-mvc可以不用导)
    删除javassist3.x,保留新版本 加入 aopalliance aspectjweave 包

    struts-plugin.xml:
    <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />

    <constant name="struts.objectFactory" value="spring" />
    struts.xml可以不用配

    struts.objectFactory.spring.autoWire是用spring插件通过覆盖(override)Struts2的ObjectFactory来增强核心框架对象的创建。当创建一个对象的时候,它会用Struts2配置文件中的class属性去和Spring配置文件中的id属性进行关联,如果能找到则由Spring创建,否则由Struts2框架自身创建,然后由Spring来装配。(默认都采用byName方式注入业务类到Action)

    步骤:配置web.xml增加spring的监听器

    配置web.xml:
    struts help spring-plugin
    spring help
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    <!-- default: /WEB-INF/applicationContext.xml -->
    </listener>

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <!-- <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value> -->
    <param-value>classpath:applicationContext.xml</param-value> //类路径src
    </context-param>


    如果class仍然使用的是类路径则所有的action将由struts管理,而且会自动根据byName注入所有的set属性

    可以通过配置常量改为byType:
    <constant name="struts.objectFactory.spring.autoWire" value="type"/>
    改成type拦截器报找不到result:input(疑似bug)


    使用Spring容器管理Action对象及他的生命周期prototype、request...
    Action中的属性注入也必须配置!

    使用通配符:
    <action name="*-*" class="{1}Action" method="{2}">
    <result>/success.jsp</result>
    </action>
    class对应spring的bean id
    <bean id="usersAction" class="com.cssl.actions.UsersAction" scope="prototype">
    <property name="usersBiz" ref="userBiz"></property>
    </bean>
    <bean name="petsAction" class="com.cssl.actions.PetsAction" scope="session">
    <property name="usersBiz" ref="userBiz"></property>
    </bean>

    在Web环境下,scope还可以使用request,session,global session!
    当使用了Spring's DispatcherServlet(springmvc)以外的Servlet 2.5及以上的Web容器时(如使用JSF或Struts),都只需要在Web应用的'web.xml'文件中增加配置:(5.5.4)
    <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener
    </listener-class>
    </listener>
    才能让Spring感知

    2.4及以下版本必须使用过滤器:
    <filter>
    <filter-name>requestContextFilter</filter-name>
    <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>requestContextFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    global session仅在Portlet的Web应用中使用,同一个全局会话共享一个实例。对于非Portlet环境,等同于session
    注意:session级别同一会话只产生一次Action对象,对于addFieldError将累加错误信息(累加到set)


    PO<->VO(DTO):
    1、导包dozer-4.2.jar,自定义两个方法
    public static void copyProperties(Object src,Object desc){
    MapperIF mif = new DozerBeanMapper();
    mif.map(src, desc);
    }
    public static <T> T copyProperties(Object src,Class<T> clazz){
    MapperIF mif = new DozerBeanMapper();
    return (T) mif.map(src, clazz);
    }

    2、使用spring自带工具org.springframework.beans.BeanUtils
    BeanUtils.copyProperties(source, target)

    3、使用struts自带工具org.apache.commons.beanutils.BeanUtils;
    BeanUtils.copyProperties(dest, orig)

    注意:根据属性名来转换,同名不同类型将注入null


    *****************************************************************************************

    五、Spring整合MyBatis|JDBC

    spring整合mybatis:导包mybatis-spring-1.x.x.jar(mybatis3.4需要1.3+)
    <!-- sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    //下面两个可以二选一
    <property name="configLocation" value="classpath:mybatis-config.xml"/> //核心配置
    <property name="mapperLocations" value="classpath:com/cssl/pojo/*.xml"/> //映射文件
    </bean>

    <!-- 为每一个dao生成对应的id,一定要注入sqlSessionFactory -->
    <bean id="udao" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface" value="com.cssl.dao.UsersDao"/>
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

    或者使用扫描包下所有类:
    注意:
    1、sqlSessionFactory可以不用注,可以没有id,自动将dao包下接口根据接口名第一个字母小写生成id名
    2、如果使用了default-autowire="byName",DataSource必须使用字符串常量
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.cssl.dao"></property>
    </bean>

    <!-- 事务 -->
    <!-- 不加事务每个dao方法为一个事务(和数据库无关),所以我们必须改变事务边界到service -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
    </bean>
    <aop:config/>和<tx:advice/>配置同hibernate

    mybatis-spring-1.x.x.jar中也有支持SqlSessionTemplate和SqlSessionDaoSupport
    mybatis整合javaee6后junit测试有bug


    Hibernate、MyBatis和JDBC的Template回调机制(模版方法设计模式)
    JdbcTemplate和DaoSupport用法(template用的多DaoSupport少)


    public List find(final String hql, final int page, final int size) {
    List result = getHibernateTemplate().execute(
    new HibernateCallback() {
    public Object doInHibernate(Session session)
    throws HibernateException, SQLException {
    Query query = session.createQuery(hql);
    query.setFirstResult((page - 1) * size);
    query.setMaxResults(size);
    return query.list();
    }
    }
    );
    return result;
    }

    HibernateTemplate传递给回调接口的session并不是org.hibernate.impl.SessionImpl类,而是SessionImpl类的一个Proxy类。HibernateTemplate的注释说明,Proxy提供了一些额外的功能,包括自动设置Cachable,Transaction的超时时间,Session资源的更积极的关闭等等。
    但遗憾的是,Hibernate的DetachedCriteria的setExecutableCriteria方法却要求将session参数强制转为SessionImpl,但是spring传过来的却是一个Proxy类,因此Spring2.5以后用executeWithNativeSession方法传递参数true强制使用SessionImpl


    Spring+JDBC: queryForXXX()|query()

    <bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
    </bean>

    Users u = template.queryForObject(sql,new BeanPropertyRowMapper<Users>(Users.class));
    List<Users> users = template.query(sql,new BeanPropertyRowMapper<Users>(Users.class));

    String sql = "select name from users";
    System.out.println(this.template.queryForList(sql, String.class));

    List<Users> list = template.query(sql, new RowMapper<Users>(){
    @Override
    public Users mapRow(ResultSet rs, int rowNum) throws SQLException {
    //rowNum=0
    //不能加判断
    //if(rs.next()){
    System.out.println(rs.getInt("id")+":"+rs.getString("name"));
    Users u = = new Users();
    u.setId(rs.getInt(1));
    u.setName(rs.getString(2));
    //}
    return u;
    }

    });

    List<Map<String, Object>> list = this.template.queryForList(sql);

    //调用存储过程 mydb->demo
    this.template.execute(new CallableStatementCreator(){
    @Override
    public CallableStatement createCallableStatement(Connection conn) throws SQLException {
    ...
    }
    }, new CallableStatementCallback<Integer>(){
    @Override
    public Integer doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
    ...
    }
    });
    或:
    this.template.execute("{call demo(?,?)}", new CallableStatementCallback<Object>() {
    @Override
    public Object doInCallableStatement(CallableStatement cs)
    throws SQLException, DataAccessException {
    ...
    return out;
    }
    });

    *****************************************************************************************

    六、Spring+Struts2+DWR整合

    1、DWR整合:(如果使用纯注解方式还要导包spring-webmvc包)
    第一种方式:
    仍然使用dwr自己的原生的servlet:
    org.directwebremoting.servlet.DwrServlet

    仍然使用dwr.xml文件配置dwr信息
    只需要将原来的creator的new改成spring,
    name值由原来的class改成beanName,
    value的值由原来的类路径改成spring的id属性的值
    dwr.xml建议放置在WEB-INF下


    第二种方式:
    使用spring管理dwr的servlet:
    org.directwebremoting.spring.DwrSpringServlet
    不在需要dwr.xml文件

    在spring的配置文件中配置dwr信息:
    添加头:
    xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr
    http://www.directwebremoting.org/schema/spring-dwr
    http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd

    <!-- dwr集成spring配置 -->
    <bean id="usersDwr" class="com.cssl.dwr.UsersDwr">
    <property name="usersBiz" ref="userBiz"/>
    <dwr:remote javascript="UsersDwr">
    <dwr:include method="getUsersSize" />
    <dwr:convert type="bean" class="com.cssl.vo.UsersVo" javascript="users"/>
    </dwr:remote>
    </bean>


    2、其他数据源形式:hibernate.cfg.xml不要再配置数据库连接,否则报BasicDataSource NotSupport

    A、使用dbcp连接池
    使用连接池导commons-dbcp-1.4.jar和commons-pool-1.6.jar
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="maxActive" value="100" />
    <property name="maxIdle" value="30" />
    <property name="maxWait" value="3000" /> 拿到连接3秒不用自动被容器回收
    </bean>


    B、C3P0连接池:
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <!-- 指定连接数据库的驱动 -->
    <property name="driverClass" value="${jdbc.driverClassName}"/>
    <!-- 指定连接数据库的URL -->
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <!-- 指定连接数据库的用户名 -->
    <property name="user" value="${jdbc.username}"/>
    <!-- 指定连接数据库的密码 -->
    <property name="password" value="${jdbc.password}"/>
    <!-- 指定连接数据库连接池的最大连接数 -->
    <property name="maxPoolSize" value="30"/>
    <!-- 指定连接数据库连接池的最小连接数 -->
    <property name="minPoolSize" value="3"/>
    <!-- 指定连接数据库连接池的初始化连接数 -->
    <property name="initialPoolSize" value="1"/>
    <!-- 指定连接数据库连接池的连接的最大空闲时间 -->
    <property name="maxIdleTime" value="20"/>
    </bean>

    C、来至于JNDI Java Naming and Directory Interface (使用tomcat作为实例)
    必须在web环境下使用
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    //代表命名服务目录名称为jdbc/mysql(实际为:java:comp/env/jdbc/testDB)
    <property name="jndiName" value="jdbc/mysql"></property>
    //加上这个的意思是不用使用java:comp/env/jdbc/testDB来设置jndiName
    <property name="resourceRef" value="true"></property>
    </bean>

    或者使用

    在xml使用jee命名空间
    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/testDB" resource-ref="true" />

    oracle11G出现的问题:
    oracle.jdbc.driver.OracleDatabaseMetaData.supportsGetGeneratedKeys()Z
    在hibernate框架上就很容易出现上面的错误,推荐大家使用下面的包ojdbc14_1_.jar


    3、懒加载问题:
    OpenSessionInView:(解决load及懒加载问题,扩大session范围到view)
    org.springframework.orm.hibernate4.support.OpenSessionInView
    <filter>
    <filter-name>openSessionInView</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    <init-param>
    <param-name>sessionFactoryBeanName</param-name>
    <!-- 默认sessionFactory,可以省略这个配置 -->
    <param-value>sessionFactory</param-value>
    </init-param>
    </filter>

    <filter-mapping>
    <filter-name>openSessionInView</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    MyBatis懒加载不需要写过滤器控制事务,业务层提交事务后每一条sql查询自动为一个独立事务!

    注意包冲突问题:javassist-x.x.x 版本冲突(ssh整合javassist包删低版本)
    懒加载问题:
    com.cssl.pojo.Users_$$_javassist_0 cannot be cast to javassist.util.proxy.Proxy


    使用了OpenSessionInView模式,Session的生命周期变长。虽然解决了Lazy Load的问题,但是带来的问题就是Hibernate的一级缓存,也就是Session级别的缓存的生命周期会变得更长,那么如果你在你的Service层做大批量的数据操作时,其实这些数据会在缓存中保留一份,这是非常耗费内存的。还有一个数据库连接的问题,存在的原因在于由于数据库的Connection是和Session绑在一起的,所以,Connection也会得不到及时的释放。因而当系统出现业务非常繁忙,而计算量又非常大的时候,往往数据连接池的连接数会不够。


    spring解决中文问题:(struts2.1.6有中文bug)
    org.springframework.web.filter.CharacterEncodingFilter
    <filter>
    <filter-name>encodingFilter</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>
    </filter>
    <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    注意事项:
    1、openSessionInView在web.xml中的配置必须在struts2的filter前面(必须struts处理完才提交,和过滤器链的执行顺序有关,先等struts过滤器执行完再执行提交的过滤器),如果没有配置事务,该过滤器会在dao层加只读事务
    2、注意必须使用sessionFactory,如果不是则必须在filter中配置
    init-param name:seesionFactoryBeanName value:新的beanName(sf)
    3、注意openSessionInView默认会认为所有事务是只读的,如果进行增删改操作会报写操作不允许异常(前提是spring本身没有配置事务)


    4、获取当前的spring容器
    方法一:(通过ServletContext加载spring容器)
    ApplicationContext ctx=WebApplicationContextUtils.getWebApplicationContext(application);


    方法二:(获取当前的spring容器,任何java类中适用)
    ApplicationContext act=ContextLoader.getCurrentWebApplicationContext();


    方法三:(重新加载spring容器)
    ApplicationContext ac=new FileSystemXmlApplicationContext("applicationContext.xml");

    Love馨蕊
  • 相关阅读:
    性能测试中的二八原则
    OS + Linux Shell Programme / 100 cases
    db postgres openGauss
    OS + Linux sshkeygen / sshcopyid / id_rsa / id_rsa.pub / authorized_keys
    OS + Android performance matrix / memory LeakCanary
    springBoot 使用ConfigurationProperties+PropertySource注解 引入yml配置文件
    SpringBoot2.0集成WebSocket,实现后台向前端推送信息
    springBoot + rabbitMQ +手动确认消息 + 控制(接口、定时任务)消费者上下线
    linux 环境下安装keepalived 并且进行简单的主备配置
    eureka 注册列表低延迟注册、剔除服务配置 实现8s延迟
  • 原文地址:https://www.cnblogs.com/yuan211/p/8334744.html
Copyright © 2011-2022 走看看