刚刚接触了SpringMVC这个框架,因此有必要把它拿过来同hibernate、Spring框架进行集成和开发一个实例,在真正企业从头开发的项目中往往一个稳定的开发环境至关重要,开发一个项目选择什么样的搭建平台也须要有经验才干够,并非说你会搭建一个开发平台然后公司就会用你搭建的开发平台。一个项目或者一个公司看中的也不是你能够搭出框架。而是在这个框架使用过程中出现的各种问题你能够解决掉。
也就是说呢,不管开发什么项目要做到稳定、环境稳定、开发成本稳定、技术稳定、换句话说就是“风险可控”,你不能说一个新的项眼下期开发到一半的时候发现这个开发环境不合适或者出现了啥新的问题你还解决不了,这不是非常淡腾的事吗?
对我们而言须要不只能够搭建一个平台并且要掌握它。掌握它能够出现的各种问题或bug。假设你没有掌握到这样的程度能够出你不过走马观花似得搭建了一个鸡窝,没有什么有用价值的,个人认为老板或者面试者也是更注重后者。所以呢,这篇博客也是注重说在搭建过程中遇到的各种问题,这也印证了打*easy但想要坐稳了不易。
本文思路
首先,看一下已经建好的整个项目文件夹结构,採用了经典三层在Eclipse里面:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlsb25nc2hlbmcxMTI1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
结构非常清晰採用了springmvc注解扫描包。里面大部分内容都是通过注解实现的可见通过注解来实现某某个功能也是一种趋势呀。注解操作简单、写的少却能实现相同的功能也是因为这个原因受到人们的欢迎。
SpringMVC与Spring集成
它同spring集成要做的事情是把bean交给spring管理,springmvc自己则不再管理bean它通过注解的方式取得spring实例化好的bean类,想让spring管理其bean就须要实例化Spring自己的WebApplicationContext对象。这个对象是上下对象程序执行全部的參数以及设置都能够从这个对象中取得bean也不列外。我们能够在web.xml文件里设置一个监听器在程序启动的时候得到WebApplicationContext对象。这个对象有它自己的属性。属性就是我们bean的配置文件。所以它才干够正确找到bean并将事实上例化。我们看一下配置文件。再看一下监听器类的源代码就能够知道原理。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/springAnnotation-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
上面配置是web.xml里配置的bean路径參数以及spring的监听器类,再看一看监听器类的源代码
package org.springframework.web.context; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; public class ContextLoaderListener extends ContextLoader
implements ServletContextListener
{
private ContextLoader contextLoader; public ContextLoaderListener()
{
} public ContextLoaderListener(WebApplicationContext context)
{
super(context);
}
}
………………………………………………………………………略…………………………………………………………………………………
这个类是监听类的部分代码,可看到它继承了ContextLoader这个类并将这个类作为成员变量传入进来,进去看一下contextloader这个类。
package org.springframework.web.context;
………………………………………………………………………略…………………………………………………………………………………
import …………
import org.springframework.util.StringUtils; public class ContextLoader
{
public static final String CONTEXT_CLASS_PARAM = "contextClass";
public static final String CONTEXT_ID_PARAM = "contextId";
public static final String CONTEXT_INITIALIZER_CLASSES_PARAM = "contextInitializerClasses";
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";
private static final Properties defaultStrategies;
private static final Map<ClassLoader, WebApplicationContext> currentContextPerThread;
private static volatile WebApplicationContext currentContext;
private WebApplicationContext context;
private BeanFactoryReference parentContextRef; public ContextLoader()
{
}
……………………………………………………略…………………………………………………………
能够看到父类中有这个变量
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
正好是我们配置文件里配置的以下的值,把bean的配置文件值通过contextConfiglocation传入了spring监听器。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/springAnnotation-*.xml</param-value>
</context-param>
这就是spring与springmvc集成的原理,看了代码相信大家已经非常清楚,能够用一句话概括;将bean交给spring管理。
仅仅有懂了原理在出现错误的时候才方便调试。以后再出现监听器错误,比如空指针了、创建失败了。不用想你就知道可能传入的配置文件没有传入你懂了原理之后也能够自己改它的源代码,传入很多其它參数等,事实上,不管是spring还是springmvc他们的监听器都是集成context这个父类而来,再往大了想想web层框架大部分都是集成该类,以后你在学习web框架的时候就会认为非常easy,你找到了他们的共同点一个网的节点你找到了剩下的就是学习他们的不同点了每一个框架都有自己的特色。我理解的也不是非常全面在你不理解时候多思考(它的设计思路)、多动手(看代码源代码)会逐步理解、逐步深入。
Spring与hibernate4集成
发现如今非常多公司也在使用ibatis、mabatis等框架,我们就一起对照着说说他们都是怎么集成,事实上都是一样的有着异曲同工的感觉思路和实现方式是一样的。
设计思路。
1.配置数据源
2.配置sessionFactory或者sqlMapclient
3.配置Transaction事务
在同数据库底层集成的框架中大部分也都是这三部,不同之处在于实现类不一样、实现的功能一样但对象不一样,举个样例;我们都知道sessionFactory属于一个对象。但在ibatis里面不是这个对象名但有相同的功能叫做。SqlMapClient.
ibatis这个框架是基于配置文件实现sql语句都写在配置文件中面,通过sqlMapclient对象能够拿到配置信息,它有两个重要的属性即数据源和xml配置文件,其它的是一些辅助參数可有可无。
对于事务也不过管理事务的类不同,但机制一样我配置的这样的都是通过代理事务类实现。优点就不多说了。
1.先看看hibernate数据源配置例如以下。
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/springmvc"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
我使用的是mysql数据库,也能够改查oracle数据库,dataSource同ibatis非常相似属性也一样。须要注意的是在数据源中往往会增加连接池配置,这个也是在这里进行配置。
2.sessionFactory
以下是hibernate、sessionFactory配置
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hbiernate.format._sql">true</prop>
</props>
</property>
<property name="configLocations">
<list>
<value>classpath*:com/tgb/web/controller/hibernate/hibernate.cfg.test.xml</value>
</list>
</property>
</bean>
对照ibatis 配置
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:sql-map-config.xml</value>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="lobHandler" ref="lobHandler"/>
</bean>
能够发现不过属性值不一样,属性都是一样的说明他们的实现方式都是一样的但实现类不一样。当中有个lobHandler属性是为了处理超大数据设置的属性。比方一个文件1G存储在数据库字段中就须要用到这个配置,进行特殊处理操作。
一个sessionFactory能够相应于多个数据源即能够对用于多个数据库,这里仅仅是配置了一个数据库,多个数据库又会涉及到分布式事务概念又会略微复杂一点,以后再介绍怎么配置,它管理着数据库中的表结构和各种表实现对表的操作。
3.事务管理
hibernate配置事务
<bean id="transactionBase" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true" abstract="true" >
<property name="transactionManager" ref="transactionManager"></property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED</prop>
</props>
</property> </bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
该事务使用了代理方式。为某个类配置事务时须要集成该事物类,例如以下
<bean id="userManagerBase" class="com.tgb.web.controller.service.UserManager">
<property name="userDao" ref="userDao"></property>
</bean> <bean id="userManager" parent="transactionBase">
<property name="target" ref="userManagerBase"></property>
</bean>
用户管理添加用户
UserAction.java 下面为对用的各层类和方法能够实现简单调用,接口里面还能够增加泛型在下篇博客中会设计接口里面怎么使用泛型操作。
@Controller
@RequestMapping("/user")
public class UserController { @Resource(name="userManager")
private IUserManager service; @RequestMapping("/addUser")
public void addUser()
{ User user=new User();
user.setId("1");
user.setAge("2");
user.setUsername("3"); service.addUser(user); }
}
IUserDao interface
public interface IUserDao { void addUser(User user);
}
userDaoImpl
private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
} @Override
public void addUser(User user) { sessionFactory.getCurrentSession().save(user);
}
IUserManager interface
public interface IUserManager { void addUser(User user);
}
userDaoImpl
public class UserManager implements IUserManager { private IUserDao userDao; public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
} @Override
public void addUser(User user) {
userDao.addUser(user);
} }
代码简单相信不用凝视也能够看懂。通过看上面的内容你也会搭建这个搭建并实现简单的实例了,假设你没有电脑能够通过手机看这篇文章。用你的手机扫描以下的二维码既能够关注,然后,回复“技术SSH”这篇文章就会自己主动发到你的手机上。
微信号为:life_talk