使用Spring4.x 搭建注解式 Spring MVC + JPA 项目

使用Spring4.x 搭建注解式 Spring MVC + JPA 项目

在我们使用Spring3.x 系列或者是更早的系列中,大都是通过xml文件来实现配置的,大量的配置文件,和繁琐的配置。
让开发特别的不爽,在4.x 系列出来后,改变了这一状况,小编也很兴奋,就搭了一个项目体验了一下。

假设我们的基础包名为:
com.mycompany.myapp

那么小编喜欢把启动class 放在 :
com.mycompany.myapp.config 下面。

首先 基础环境必须是支持Servlet3及以上,小编使用的 Tomcat8 。
(注:在Servlet3 已经可以通过实现ServletContainerInitializer接口来配置 Filter,Servlet 和 Listener ,
Spring 进行了一些封装实现WebApplicationInitializer接口也可以达到这一效果。)

小编这里是通过三个java文件来实现的。
1。ApplicationBoot (启动类)
2。MvcConfig (mvc 的配置类)
3。RootConfig (组件配置类)

先看 ApplicationBoot 继承的是AbstractAnnotationConfigDispatcherServletInitializer
(如果需要自己控制ApplicationContext的实现类型也可以继承AbstractDispatcherServletInitializer)

public class ApplicationBoot extends 
                AbstractAnnotationConfigDispatcherServletInitializer{

    /**
     * 该方法定义的是全局的 applicationContext
     * 在初始化时需要去扫描哪些带注解(如:@Configuration)的类
     */
    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }

    /**
     * 该方法定义的时Servlet级别的applicationContext
     * 在初始化时需要去扫描哪些带注解(如:@Configuration)的类
     */
    @Override
    protected Class[] getServletConfigClasses() {
        return new Class[]{MvcConfig.class};
    }

    /**
     * 定义 DispatcherServlet 拦截的路径
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

}

那么全局的 ApplicationContext(root) 和 Servlet级的 ApplicationContext 有什么区别呢?
1.他们是父子关系,root 是 Servlet级的 父环境,也就是说 Servlet级的环境中可以访问到root环境中的实例,反之则不成立
2.项目中有几个Servlet就可以对应有几个ApplicationContext,他们都共享一个root 达到了多Servlet的实例共享

那么我们怎么来分配实例具体由哪个环境来持有呢,通常我们可以把Controller层 交给Servlet级的环境来持有,将Dao和Service层交于root来持有,当然面对项目中只有一个Servlet的情况下也可以不配置root环境(那么就需要继承AbstractDispatcherServletInitializer来精确配置)

好我们来看 MvcConfig 类

@EnableWebMvc
@Configuration
@ComponentScan("com.mycompany.myapp.controller")
public class MvcConfig extends WebMvcConfigurerAdapter{

    /**
     * 设置静态文件的映射关系
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    /**
     * 配置视图处理技术,这里使用了jsp方式
     */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/WEB-INF/views",".jsp");
    }

    /**
     * 配置使用 服务器默认Servlet 来处理静态资源。DispatcherServlet 我们设置了拦截所以,所以在找静态资源的选择让default 去做。
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    /**
     * 添加拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addWebRequestInterceptor(openEntityManagerInViewInterceptor());
    }

    /**
     * 使用JPA  懒加载数据容易出现 no session 问题,可以加这个拦截器,
     * 相对使用Filter 来说, 这个数据库事物是在找到相应的处理者之后才会打开
     */
    @Bean
    public OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor(){
        return new OpenEntityManagerInViewInterceptor();
    }

}

好再看一下 RootConfig类

@Configuration
@EnableTransactionManagement
@ComponentScan({"com.mycompany.myapp.service"
                    ,"com.mycompany.myapp.dao"})
public class RootConfig {

    /**
     * 配置项目的配置文件信息
     */
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer config  = new PropertySourcesPlaceholderConfigurer();
        config.setLocation(new ClassPathResource("META-INF/system-cnf.properties"
                                            , AbstractMvcConfigurer.class.getClassLoader()));

        return config;
    }


    /**
     * 小编比较喜欢通过配置文件来管理数据配置信息,而没有把这部分信息配置在 persistence.xml中
     */
    @Bean
    public DataSource  dataSource(
            @Value("${db.url}")String url,
            @Value("${db.user}")String username,
            @Value("${db.password}")String password,
            @Value("${db.driver}")String driverClassName
            ){


        DriverManagerDataSource dataSource = new DriverManagerDataSource(url, username, password);
        dataSource.setDriverClassName(driverClassName);

        return dataSource;
    }

    /**
     * JPA 实体管理工厂
     */
    @Bean
    public LocalContainerEntityManagerFactoryBean  entityManagerFactory(DataSource dataSource){

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();

        factory.setPersistenceUnitName("PU");
        factory.setDataSource(dataSource);

        return factory;
    }

    /**
     * JPA 事物处理
     */
    @Bean
    public JpaTransactionManager  jpaTransactionManager(EntityManagerFactory  factory){
        JpaTransactionManager  manager = new JpaTransactionManager();

        manager.setEntityManagerFactory(factory);

        return manager;
    }
    /**
     * 事物异常处理
     */
    @Bean
    public PersistenceExceptionTranslationPostProcessor  persistenceExceptionTranslationPostProcessor(){
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

到这里我们还需要在 META-INF 下面放置
persistence.xml 文件
和 system-cnf.properties 的配置文件。

事务操作 仅需要在 相应方法上添加@Transactional 即可,希望小编的分享对您有所帮助。

最后贴上小编的 pom 的 jar 依赖吧。

    <properties>
        <org.springframework-version>4.1.7.RELEASEorg.springframework-version>
        <org.aspectj-version>1.6.10org.aspectj-version>
        <org.slf4j-version>1.6.6org.slf4j-version>
    properties>

<dependencies>
     <dependency>
              <groupId>commons-iogroupId>
                    <artifactId>commons-ioartifactId>
                         <version>2.1version>
             dependency>

    <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-databindartifactId>
            <version>2.6.0version>
        dependency>

    
        <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-txartifactId>
                <version>${org.springframework-version}version>
        dependency>
         <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-ormartifactId>
            <version>${org.springframework-version}version>
        dependency>

        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>${org.springframework-version}version>
            <exclusions>
                
                <exclusion>
                    <groupId>commons-logginggroupId>
                    <artifactId>commons-loggingartifactId>
                 exclusion>
            exclusions>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>${org.springframework-version}version>
        dependency>

        
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjrtartifactId>
            <version>${org.aspectj-version}version>
        dependency>   

        
        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-apiartifactId>
            <version>${org.slf4j-version}version>
        dependency>
        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>jcl-over-slf4jartifactId>
            <version>${org.slf4j-version}version>
            <scope>runtimescope>
        dependency>
        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-log4j12artifactId>
            <version>${org.slf4j-version}version>
            <scope>runtimescope>
        dependency>
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>1.2.15version>
            <exclusions>
                <exclusion>
                    <groupId>javax.mailgroupId>
                    <artifactId>mailartifactId>
                exclusion>
                <exclusion>
                    <groupId>javax.jmsgroupId>
                    <artifactId>jmsartifactId>
                exclusion>
                <exclusion>
                    <groupId>com.sun.jdmkgroupId>
                    <artifactId>jmxtoolsartifactId>
                exclusion>
                <exclusion>
                    <groupId>com.sun.jmxgroupId>
                    <artifactId>jmxriartifactId>
                exclusion>
            exclusions>
            <scope>runtimescope>
        dependency>

        
        <dependency>
              <groupId>org.hibernategroupId>
              <artifactId>hibernate-entitymanagerartifactId>
              <version>5.0.3.Finalversion>
              <scope>compilescope>
            dependency>

            <dependency>
                <groupId>org.hibernategroupId>
                <artifactId>hibernate-validatorartifactId>
                <version>5.2.2.Finalversion>
            dependency>


        
        <dependency>
            <groupId>javax.injectgroupId>
            <artifactId>javax.injectartifactId>
            <version>1version>
        dependency>

        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>servlet-apiartifactId>
            <version>2.5version>
            <scope>providedscope>
        dependency>
        <dependency>
            <groupId>javax.servlet.jspgroupId>
            <artifactId>jsp-apiartifactId>
            <version>2.1version>
            <scope>providedscope>
        dependency>
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>jstlartifactId>
            <version>1.2version>
        dependency>




        
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.7version>
            <scope>testscope>
        dependency>        
    dependencies>

你可能感兴趣的:(Spring)