丢掉xml使用JavaConfig配置Spring

Spring JavaConfig

最近撸了一遍Spring action 4,发现里面讲的都不再使用xml文件来配置spring,全都采用Java代码来配置.

用Java代码配置的话,感觉要比xml更便于维护,而且用代码肯定比xml更爽嘛

下面来一步步用JavaConfig搭一个Spring工程

那在用xml配置的时候,项目都是从加载web.xml文件再扫描到各种spring-*.xml文件

那不用xml文件,项目从哪里启动呢?

那就要靠这个类了,AbstractAnnotationConfigDispatcherServletInitializer,这个就相当于web.xml啦,在这里面可以配置上下文,DispatcherServlet,过滤器等等bean;

首先咱先创建一个类SpittrWebAppInitialzer

package com.fireyao;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;

public class SpittrWebAppInitialzer extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * 配置root上下文,如Jpa数据源等等的配置
     * @return
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }

    /**
     * 配置dispatcher servlet
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    /**
     * 将DispatcherServlet映射到 "/"
     * 指定开始被servlet处理的url,配置从/开始  
     * @return
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * 这里注册的所有过滤器,都会映射到DispatcherServlet
     * 就是说这里的过滤器过滤规则是 /*
     * 所有的请求都会先到这里注册的过滤器中
     *
     * @return
     */
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{
                new CharacterEncodingFilter("UTF-8", true)
        };
    }
}

SpittrWebAppInitialzer类里面加载了RootConfigWebConfig两个配置类,

再创建这两个类以及相关的配置(以下省略package和import)

RootConfig

/**
 * 相当于applicationContext.xml
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.fireyao.repository"},
        entityManagerFactoryRef = "entityManagerFactory",
        transactionManagerRef = "transactionManager")
@PropertySource(value = {"classpath:db.properties", "classpath:hibernate.properties", "classpath:app.properties"})
@ComponentScan(basePackages = "com.fireyao",
        excludeFilters = {
                @ComponentScan.Filter(
                        type = FilterType.ANNOTATION, value = EnableWebMvc.class
                )})
@EnableAspectJAutoProxy(proxyTargetClass = true)
/**
 *   proxyTargetClass = true ==> 使用cglib代理
 *   proxyTargetClass = false(默认) ==> 使用JDK代理
 */
public class RootConfig {


    @Value(value = "${db.driver:org.postgresql.Driver}")
    private String DRIVERCLASSNAME;

    @Value("${db.username}")
    private String USERNAME;

    @Value("${db.password}")
    private String PASSWORD;

    @Value("${db.jdbcURL}")
    private String URL;

    @Value("${hibernate.hbm2dll.create_namespaces}")
    private String CREATE_NAMESPACES;

    @Value("${hibernate.hbm2ddl.auto}")
    private String HBM2DDL_AUTO;

    @Value("${hibernate.show_sql}")
    private String SHOW_SQL;

    @Value("${hibernate.format_sql}")
    private String FORMAT_SQL;

    @Value("${hibernate.generate_statistics}")
    private String GENERATE_STATISTICS;
    
  /**
   * 配置数据源
   */
    @Bean(name = "dataSource")
    public DruidDataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(DRIVERCLASSNAME);
        dataSource.setUrl(URL);
        dataSource.setUsername(USERNAME);
        dataSource.setPassword(PASSWORD);

        /*  配置初始化大小、最小、最大*/
        dataSource.setInitialSize(5);
        dataSource.setMinIdle(5);
        dataSource.setMaxActive(20);
        /* 配置获取连接等待超时的时间*/
        dataSource.setMaxWait(30000);
        /*配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒*/
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        /*配置一个连接在池中最小生存的时间,单位是毫秒*/
        dataSource.setMinEvictableIdleTimeMillis(300000);
        /*申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效*/
        dataSource.setTestWhileIdle(true);
        dataSource.setValidationQuery("select 1");
        return dataSource;
    }

    @Bean
    public HibernateJpaVendorAdapter hibernateJpaVendorAdapter() {
        return new HibernateJpaVendorAdapter();
    }
    
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DruidDataSource dataSource,HibernateJpaVendorAdapter hibernateJpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setDataSource(dataSource);
        entityManagerFactory.setJpaVendorAdapter(hibernateJpaVendorAdapter);
        entityManagerFactory.setPackagesToScan("com.fireyao.domain");

        /*指定JPA属性;如Hibernate中指定是否显示SQL的是否显示、方言等*/
        Map<String, Object> jpaProp = new HashMap();
        jpaProp.put("hibernate.dialect", new PostgisDialect());
        jpaProp.put("hibernate.hbm2ddl.auto", HBM2DDL_AUTO);
        jpaProp.put("hibernate.show_sql", SHOW_SQL);
        jpaProp.put("hibernate.generate_statistics", GENERATE_STATISTICS);
        jpaProp.put("hibernate.format_sql", FORMAT_SQL);
        jpaProp.put("hibernate.hbm2dll.create_namespaces", CREATE_NAMESPACES);
        entityManagerFactory.setJpaPropertyMap(jpaProp);
        return entityManagerFactory;
    }

    /**
     * 事务管理器
     *
     * @param entityManagerFactory
     * @return
     */
    @Bean(name = "transactionManager")
    public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory.getObject());
    }
}

WebConfig

/**
 * 相当于springmvc-servlet.xml
 */
@Configuration
@EnableWebMvc//启用spring mvc
@ComponentScan(basePackages = "com.fireyao.controller") //启用组件扫描
public class WebConfig extends WebMvcConfigurerAdapter {


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        //处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(fastConverter);
    }


    /**
     * Thymeleaf视图解析器
     *
     * @param springTemplateEngine
     * @return
     */
    @Bean
    public ThymeleafViewResolver viewResolver(SpringTemplateEngine springTemplateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(springTemplateEngine);
        viewResolver.setCharacterEncoding("utf-8");
        return viewResolver;
    }

    /**
     * 模版引擎
     *
     * @param iTemplateResolver
     * @return
     */
    @Bean
    public SpringTemplateEngine templateEngine(ITemplateResolver iTemplateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(iTemplateResolver);
        return templateEngine;
    }

    /**
     * Thymeleaf3.0之后
     * Thymeleaf模版解析器
     *
     * @return
     */
    @Bean
    public ITemplateResolver iTemplateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setTemplateMode("HTML5");
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("HTML");
        templateResolver.setCharacterEncoding("utf-8");

        templateResolver.setCacheable(false);
        return templateResolver;
    }

    /**
     * Thymeleaf3.0之前
     * Thymeleaf模版解析器
     * @return
     */
  /*  @Bean
    public TemplateResolver templateResolver() {
        TemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setPrefix("/WEB-INF/VIEWS/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode("HTML5");
        resolver.setCacheable(false);
        return resolver;
    }*/


    /**
     * 配置静态资源的处理
     * 要求DispatcherServlet将对静态资源的请求转发到Servlet容器中默认的Servlet上
     * 而不是使用DispatcherServlet本身来处理此类请求。
     *
     * @param configurer
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    /**
     * 配置视图解析器
     * ==> JSP视图
     *
     * @return
     */
    /*@Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }*/
}

@Configuration 标注为配置类

@EnableTransactionManagement注解开启注解式事务的支持。

@EnableJpaRepositories注解开启对Spring Data JPA Repostory的支持

@PropertySource 扫面db.properties等配置文件,可以用@Value注解取到properties中的值

@ComponentScan 配置扫描类包 相当于<context:component-scan base-package="com.fireyao"/>

@EnableAspectJAutoProxy 表示开启AOP代理自动配置

@EnableAspectJAutoProxy中proxyTargetClass属性
​ proxyTargetClass = true ==> 使用cglib代理
​ proxyTargetClass = false(默认) ==> 使用JDK代理

那spring最基本的JavaConfig就这样了.

是不是看上去很舒服,果然还是要用Java代码才爽.

原文链接:丢掉xml使用JavaConfig配置Spring | 火尧

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容