java注解方式(不用xml)配置web框架spring+SpringMVC

公司现在用了gradle构建工具
而且用java注解的方式配置项目,不再使用xml的方式,因为网上这方面教程比较少,所以在此记录一个基本的框架的搭建,包括测试类的写法!
框架:spring+springMVC+hibernate
构建工具:gradle
开发工具:eclipse
github地址:https://github.com/gyb123456/MyGradle
项目结构如下:这里写图片描述
我把项目源码放到我的github上了;

主要看下com.sys包就行了,我主要讲解这里的。看到和sys平级的三个java文件了没,这就是项目配置的3个java类。
先给3个参考链接
1、Spring实战5-基于Spring构建Web应用
https://segmentfault.com/a/1190000004343063?_ea=575820
2、单元测试配置
http://www.infoq.com/cn/articles/Unit-Testing-Complete-Integration-Testing-Begins
3、别人的配置
http://blog.csdn.net/csdn_xuexiaoqiang/article/details/71844535
4、 写给java web一年左右工作经验的人
https://my.oschina.net/aaron74/blog/282304
我就是参考它们写的。


1、先说下DispatcherServletInit类继承自
AbstractAnnotationConfigDispatcherServletInitializer,tomcat启动时会自动扫描继承该类的文件,所以这个文件是整个项目的程序入口,在这里配置根容器、Spring mvc容器,拦截请求等,具体的自己看代码注释吧。

/**
 *DispatcherServletInit类
 * 整个项目的程序入口
 * @author gyb
 *
 */
package com;

import javax.servlet.Filter;

import org.springframework.orm.hibernate4.support.OpenSessionInViewFilter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class DispatcherServletInit extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override //根容器,用于获取Spring应用容器的配置文件
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{RootConfig.class};
    }

    @Override //Spring mvc容器,是根容器的子容器
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{WebConfig.class};
    }

    @Override //"/"表示由DispatcherServlet处理所有向该应用发起的请求。
    protected String[] getServletMappings() {
        return new String[]{"/"};   
    }

    @Override
    protected Filter[] getServletFilters() {
    //          OpenSessionInViewFilter  openSessionInViewFilter  = new OpenSessionInViewFilter ();
            CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();  
            characterEncodingFilter.setEncoding("UTF-8");  
            characterEncodingFilter.setForceEncoding(true);  
            return new Filter[] {characterEncodingFilter,characterEncodingFilter};  
//      return super.getServletFilters();

    }

}

2、RootConfig类

package com;

import java.beans.PropertyVetoException;
import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.sys.biz.impl.ConstTypeBizImpl;

@Configuration
/*  @EnableAspectJAutoProxy:开启AOP代理自动配置
    proxyTargetClass=true:表示使用CGLib动态代理技术织入增强,决定是基于接口的还是基于类的代理被创建。默认为false(JDK代理)
    即<aop:aspectj-autoproxy proxy-target-class="true"/> 
*/
@EnableAspectJAutoProxy(proxyTargetClass=true) //解决实现接口后,spring不能创建类实例的问题
@EnableScheduling //通过@EnableScheduling注解开启对计划任务的支持
@ComponentScan(
    basePackages={"com.sys,com.base"},
    excludeFilters={//设置不扫描的文件,这里会排除springMVC扫描过的包
        @Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)
    }
)
//启用注解事务管理,等同于xml配置方式的 <tx:annotation-driven />
@EnableTransactionManagement
public class RootConfig {

    /**配置C3P0
     * */
    @Bean
    public ComboPooledDataSource dataSource() throws PropertyVetoException{
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        cpds.setDriverClass("com.mysql.cj.jdbc.Driver");
        cpds.setJdbcUrl("jdbc:mysql://10.1.30.207:3306/InfoIssue?characterEncoding=utf8");
        cpds.setUser("root");
        cpds.setPassword("root");
        return cpds;
    }

    /**Hibernate SessionFactory
     * */
    @Bean
    public LocalSessionFactoryBean sessionFactory(DataSource dataSource){
        LocalSessionFactoryBean sf = new LocalSessionFactoryBean();
        sf.setDataSource(dataSource);
        sf.setPackagesToScan(new String[]{"com"});
        Properties props = new Properties();
        props.setProperty("dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        sf.setHibernateProperties(props);
        return sf;
    }

    @Bean
    public PlatformTransactionManager annotationDrivenTransactionManager(SessionFactory sessionFactory) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory);
        return transactionManager;
    }
    //这是一个Bean后置处理器,它会在所有拥有#Repository注解的类上添加一个通知器,这样就会捕获任何平台相关的异常并以Spring非检查型访问异常的形式重新抛出。
    @Bean
    public BeanPostProcessor persistenceTranslation(){
        return new PersistenceExceptionTranslationPostProcessor();
    }

}

3、WebConfig类

package com;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc   //启用Spring MVC组件
@ComponentScan("com.sys.ctrl")  //配置扫描的ctrl层
public class WebConfig extends WebMvcConfigurerAdapter{

    //配置JSP视图解析器
    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/JSP/");
        resolver.setSuffix(".jsp");
        //可以在JSP页面中通过${}访问beans
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

    //配置静态资源的处理
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();//把针对静态资源的请求转交给servlert容器的default servlet处理
    }

    /**
     * Jackson配置
     * @return
     */
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
//      MediaType mediaType1 = new MediaType("application\\json");
//      MediaType mediaType2 = new MediaType("charset=UTF-8");
//      supportedMediaTypes.add(mediaType1);
//      supportedMediaTypes.add(mediaType2);

        supportedMediaTypes = MediaType.parseMediaTypes("application/json; charset=utf-8");

        converter.setSupportedMediaTypes(supportedMediaTypes );
        return converter;
    }
    /*//如何在Spring MVC中统一对返回的Json进行加密?http://www.tuicool.com/articles/E3I3qyi
     * @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        return new MappingJackson2HttpMessageConverter() {
            //重写writeInternal方法,在返回内容前首先进行加密
            @Override
            protected void writeInternal(Object object,
                                         HttpOutputMessage outputMessage) throws IOException,
                    HttpMessageNotWritableException {
                //使用Jackson的ObjectMapper将Java对象转换成Json String
                ObjectMapper mapper = new ObjectMapper();
                String json = mapper.writeValueAsString(object);
                LOGGER.error(json);
                //加密
                String result = json + "加密了!";
                LOGGER.error(result);
                //输出
                outputMessage.getBody().write(result.getBytes());
            }
        };
    }*/
    /**
     * Jackson配置
     * 添加自定义转换器
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(mappingJackson2HttpMessageConverter());
        super.configureMessageConverters(converters);
    }
}

这些文件都是我遇到以后填好的坑,每个细节都得注意,一个注解都不能少。

下面是build.gradle文件的配置,包括插件或者jar的版本号都要对应,否则项目会报错,这也是我遇到坑以后,在百度上查到的并填的坑!

/*
 * This build file was generated by the Gradle 'init' task.
 *
 * user guide available at https://docs.gradle.org/3.3/userguide/tutorial_java_projects.html
 */

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'com.bmuschko.tomcat'

sourceCompatibility = 1.8
version = '1.0'

//解决编码GBK的不可映射字符
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

repositories {
    maven{ url "http://repo.spring.io/release"}
    jcenter()
}

dependencies {
    def tomcatVersion = '8.0.42'
    tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
           "org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}",
           "org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}"
}

dependencies {
    compile 'org.springframework:spring-context:4.3.8.RELEASE',
            'org.springframework:spring-web:4.3.8.RELEASE',
            'org.springframework:spring-webmvc:4.3.8.RELEASE',
            'org.springframework:spring-orm:4.3.8.RELEASE',

            'org.hibernate:hibernate-core:4.3.11.Final',

            'com.mchange:c3p0:0.9.5.2',

            'mysql:mysql-connector-java:6.0.6',

            'com.jcraft:jsch:0.1.46',

            //jackson包
            'com.fasterxml.jackson.core:jackson-databind:2.6.1'
            'com.fasterxml.jackson.core:jackson-annotations:2.6.1'
            'com.fasterxml.jackson.core:jackson-core:2.6.1'

    providedCompile 'javax.servlet:javax.servlet-api:4.0.0-b07' //用4.0.0-b07版本,否则3.0坑爹
    testCompile 'junit:junit:4.12',
                'org.springframework:spring-test:4.3.8.RELEASE'
}

buildscript {
    repositories {
        jcenter()
    }
    dependencies{
        classpath 'com.bmuschko:gradle-tomcat-plugin:2.2.5'
    }
}

test{
    testLogging{
        showStandardStreams = true
        events 'started', 'passed', 'skipped', 'failed'
    }
}

4、至此项目已经搭建好了,但是呢,测试文件还没说。我写下测试类sys.dao下面的ConstTypeTest的配置

package com.sys.dao;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import com.RootConfig;
import com.WebConfig;
import com.sys.biz.impl.ConstDictBizImpl;
import com.sys.ctrl.ConstDictCtrl;
import com.sys.ctrl.ConstTypeCtrl;
import com.sys.po.ConstDict;

@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes=RootConfig.class)

@WebAppConfiguration //(value = "src/main/webapp")
@ContextHierarchy({
        @ContextConfiguration(name = "parent", classes = RootConfig.class),
        @ContextConfiguration(name = "child", classes = WebConfig.class)})
//@Transactional
public class ConstTypeTest {

    @Autowired
    private ConstTypeCtrl ConstTypeBizImpl; 
    @Autowired
    private ConstDictCtrl ConstDictCtrl;
    @Autowired
    private ConstDictBizImpl constDictBizImpl;
    @Test
    public  void findAll() {
//      List<ConstType> list = ConstTypeBizImpl.findAll();
        ConstDict po = new ConstDict();
        po.setVal("lll");
        po.setName("啦啦啦");
        po.setTypeId(1);
        ConstDictCtrl.save(po, null);
//      constDictBizImpl.save(po);



        System.out.println("=============");
    }
}

结束!

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Gyb_csdn/article/details/73771071
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭