通过applicationContext.xml解读SSH启动与运行过程(2)

来源:互联网 发布:免费的gis软件 编辑:程序博客网 时间:2024/06/07 17:59
    <!-- 头引用略过 -->

 

    <!--开启aop切面代理 -->

    <aop:aspectj-autoproxy/>

通过配置织入@Aspectj切面,通过aop命名空间的<aop:aspectj-autoproxy/>声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被<aop:aspectj-autoproxy/>隐藏起来了

    <!--开启注解 -->

    <context:annotation-config/>

    并且为后面编程式事务的@Transaction提供支持

<!-- 开启自动扫描后,不需配置注解,该选项包内含开启注解 -->

    <context:component-scanbase-package="com.idomov"/>

扫描指定包下的全部的标有@Component的类,并注册成bean.也就是@Component的子注解@Service,@Reposity等

    <!--########################################### sessionFactory管理 ########################################### -->

    <!--引入外部的properties文件 -->

    <context:property-placeholderlocation="classpath*:jdbc.properties"/>

    <!--DataSource配置 -->

<beanid="myDataSource"class="com.jolbox.bonecp.BoneCPDataSource"

        destroy-method="close">

        <propertyname="driverClass"value="${jdbc.driver}"/>

        <propertyname="jdbcUrl"value="${jdbc.url}"/>

        <propertyname="username"value="${jdbc.username}"/>

        <propertyname="password"value="${jdbc.password}"/>

       

         <!--检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0 --> 

        <propertyname="idleConnectionTestPeriod"value="${boncp.idleConnectionTestPeriod}"/> 

        <!--连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0 --> 

        <propertyname="idleMaxAge"value="${boncp.idleMaxAge}"/> 

        <!--分区数,默认值2,最小1,推荐3-4,视应用而定--> 

        <propertyname="partitionCount"value="${boncp.partitionCount}"/>

        <!--每个分区最小的连接数 --> 

        <propertyname="minConnectionsPerPartition"value="${boncp.minConnectionsPerPartition}"/> 

        <!--每个分区最大的连接数 --> 

        <propertyname="maxConnectionsPerPartition"value="${boncp.maxConnectionsPerPartition}"/>

        <!--创建之后最大存活时间单位秒 -->

        <propertyname="maxConnectionAge"value="${boncp.maxConnectionAge}"/>

    </bean>

 

    <!--###########################################jpa entityManagerFactory

        ###########################################-->

 

    <!--对标注@PersistenceContext的类经行增强,引入代理后的EntityManager实例 -->

    <bean

    class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    <!--对标注@Repository的类经行增强,将EntityManager异常转换为SpringDAO体系的异常 -->

    <bean  class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

    <beanid="entityManagerFactory"

    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <propertyname="dataSource"ref="myDataSource"/>

        <propertyname="persistenceXmlLocation"value="classpath:META-INF/persistence.xml"/>

        <propertyname="persistenceUnitName"value="idomov"/>

        <propertyname="jpaVendorAdapter">

            <beanclass="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

                <propertyname="database"value="MYSQL"/>

                <propertyname="showSql"value="true"/>

                <propertyname="generateDdl"value="true"/>

                <propertyname="databasePlatform"value="org.hibernate.dialect.MySQL5InnoDBDialect"/>

            </bean>

        </property>

        <propertyname="jpaProperties">

            <props>

                <propkey="hibernate.show_sql">false</prop>

                <prop key="hibernate.format_sql">true</prop>

                <propkey="hibernate.dialect">${hibernate.dialect}</prop>

                <propkey="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>

                <propkey="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>

                <propkey="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>

               

            </props>

        </property>

 

    </bean>

    <!-- JPA事务管理 -->

    <beanid="transactionManager"class="org.springframework.orm.jpa.JpaTransactionManager">

        <propertyname="entityManagerFactory"ref="entityManagerFactory"></property>

    </bean>

    在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。

    <tx:annotation-driventransaction-manager="transactionManager"/>

声明使用注解让Spring管理事务,注解的方式是一种编程式事务

声明式事务有三种方式实现:第一种,使用tx标签方式;第二种,使用代理方式;第三种,使用拦截器

 

    <!--###########################################jbpmentityManagerFactory########################################### -->

    <!--配置 sessionFactory -->

    <beanid="sessionFactory"

        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">


可见生成的是LocalSessionFactoryBean而非SessionFactory。从LocalSessionFactoryBean的实现上看

LocalSessionFactoryBean   extends AbstractSessionFactoryBean implements BeanClassLoaderAware

在AbstractSessionFactoryBeanimplements FactoryBean<SessionFactory>中有

private SessionFactory sessionFactory;     

    public Object getObject(); {     

     return this.sessionFactory;     

 }    

 

顺藤摸瓜,AbstractSessionFactoryBeanextends HibernateExceptionTranslator

  implements FactoryBean<SessionFactory>,InitializingBean, DisposableBean

而FactoryBean的代码为:

publicinterface FactoryBean<T> {

    T getObject() throws Exception;

    Class<?> getObjectType();

    boolean isSingleton();

}

可见Spring在装配的时候如果发现实现了FactoryBean接口就会使用FactoryBean的getObject()方法返回对象的装配。当使用LocalSessionFactoryBean,比如applicationContext.getBean(“SessionFactory”)时,Spring返回的不是LocalSessionFactoryBean本身,他会自动调用getObject()方法,把真正的sessionFactory返回。所以不需要显式地创建一个sessionFactory,直接引用LocalSessionFactoryBean就可以

        <propertyname="dataSource"ref="myDataSource"/>

        <propertyname="configLocation">

            <value>classpath:hibernate.cfg.xml</value>

        </property>

        <propertyname="mappingResources">

            <list>

                <!-- <value>config/hibernate/hbm/WorkFlow.hbm.xml</value>-->

            </list>

        </property>

        <propertyname="hibernateProperties">

            <value>

                hibernate.dialect=${hibernate.dialect}

<!--                hibernate.hbm2ddl.auto=update

                hibernate.show_sql=${hibernate.show_sql}

                hibernate.format_sql= ${hibernate.format_sql} -->

                hibernate.jdbc.batch_size=${hibernate.jdbc.batch_size}

                hibernate.jdbc.fetch_size=${hibernate.jdbc.fetch_size}

            </value>

        </property>

    </bean>

 

 

 

    <!--###########################################缓存管理########################################### -->

    <!--缓存定义 -->

    <beanid="defaultCacheManager"

        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">

        <propertyname="configLocation"value="classpath:ehcache.xml">

        </property>

    </bean>

    <!--注解实现缓存ehcache -->

    <!--<ehcache:annotation-driven cache-manager="defaultCacheManager"/> -->

</beans>

1.Hibernate一级缓存又称为“Session的缓存”。

Session内置不能被卸载,Session的缓存是事务范围的缓存(Session对象的生命周期通常对应一个数据库事务或者一个应用事务)。

一级缓存中,持久化类的每个实例都具有唯一的OID。


2.Hibernate二级缓存又称为“SessionFactory的缓存”。

由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。

第二级缓存是可选的,是一个可配置的插件,默认下SessionFactory不会启用这个插件。

Hibernate查找对象如何应用缓存?
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;

查不到,如果配置了二级缓存,那么从二级缓存中查;

如果都查不到,再查询数据库,把结果按照ID放入到缓存删除、更新、增加数据的时候,同时更新缓存。


.一级缓存应用: save()。当session对象调用save()方法保存一个对象后,该对象会被放入到session的缓存中。 get()和load()。当session对象调用get()或load()方法从数据库取出一个对象后,该对象也会被放入到session的缓存中。 使用HQL和QBC等从数据库中查询数据。

.二级缓存的管理:

evict(Class arg0, Serializable arg1)将某个类的指定ID的持久化对象从二级缓存中清除,释放对象所占用的资源。

sessionFactory.evict(Customer.class, new Integer(1));  

evict(Class arg0)  将指定类的所有持久化对象从二级缓存中清除,释放其占用的内存资源。

sessionFactory.evict(Customer.class);  

evictCollection(String arg0)  将指定类的所有持久化对象的指定集合从二级缓存中清除,释放其占用的内存资源。

sessionFactory.evictCollection("Customer.orders");  


//--------------------------

JPA和Hibernate之间的关系,可以简单的理解为JPA是标准接口,Hibernate是实现。Hibernate主要是通过三个组件来实现的,及hibernate-annotation、hibernate-entitymanager和hibernate-core。

hibernate-annotation是Hibernate支持annotation方式配置的基础,它包括了标准的JPA annotation以及Hibernate自身特殊功能的annotation。

hibernate-core是Hibernate的核心实现,提供了Hibernate所有的核心功能。

hibernate-entitymanager实现了标准的JPA,可以把它看成hibernate-core和JPA之间的适配器,它并不直接提供ORM的功能,而是对hibernate-core进行封装,使得Hibernate符合JPA的规范。

EntityManagerFactory对象的实现是EntityManagerFactoryImpl类,这个类有一个最重要的private属性就是Hibernate的核心对象之一SessionFactory。这个类最重要的方法是createEntityManager,来返回EntityMnagaer对象,而sessionFactory属性也传入了该方法。

EntityManager对象的实现是EntityManagerImpl类,这个类继承自AbstractEntityManagerImpl类,在AbstractEntityManager类中有一个抽象方法getSession来获得Hibernate的Session对象,正是在这个Session对象的实际支持下,EntityManagerImpl类实现了JPA的EntityManager接口的所有方法,并完成实际的ORM操作。

此外,hibernate-entitymanager 包中还有QueryImpl类利用EntityManagerImpl的支持实现了JPA的Query接口;TransactionImpl利用EntityManagerImpl的支持实现了JPA的EntityTransaction接口。

至此,Hibernate通过hibernate-entitymanager包完成了对于JPA的全部支持工作。

//--------------------------

hibernate 简介:
hibernate是一个开源框架,它是对象关联关系映射的框架,它对JDBC做了轻量级的封装,而我们java程序员可以使用面向对象的思想来操纵数据库。
hibernate核心接口
session:负责被持久化对象CRUD操作
sessionFactory:负责初始化hibernate,创建session对象
configuration:负责配置并启动hibernate,创建SessionFactory
Transaction:负责事物相关的操作
Query和Criteria接口:负责执行各种数据库查询

hibernate工作原理:

1.通过Configuration config = new Configuration().configure();//读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息
3.通过SessionFactory sf = config.buildSessionFactory();//创建SessionFactory
4.Session session = sf.openSession();//打开Sesssion
5.Transaction tx = session.beginTransaction();//创建并启动事务Transation
6.persistent operate操作数据,持久化操作
7.tx.commit();//提交事务
8.关闭Session
9.关闭SesstionFactory


如何优化Hibernate?
1.使用双向一对多关联,不使用单向一对多
2.灵活使用单向一对多关联
3.不用一对一,用多对一取代
4.配置对象缓存,不使用集合缓存
5.一对多集合使用Bag,多对多集合使用Set
6. 继承类使用显式多态

7. 表字段要少,表关联不要怕多,有二级缓存撑腰


0 0
原创粉丝点击