Spring:使基于Java的配置更加优雅

大家好,我很久没有写新文章了。 积累了很多资料,需要在不久的将来在我的博客中发布。 但是现在我想谈谈Spring MVC应用程序配置。 确切地说,我想谈谈基于Java的Spring配置。

尽管在3.0版本中引入了基于Spring Java的配置,但是许多开发人员仍然使用基于XML的方法。 我个人使用基于注释的配置,因为它们在管理,开发和维护方面更加方便。 如果您已经阅读过我的博客,那么您可能会注意到在所有代码示例中,我都完全使用基于Java的配置。

不久前,我对我的项目进行了代码审查。 我注意到配置结构有问题。 对我来说,有两个方面很糟糕:

  • 所有bean都配置在一个类中
  • 在Web应用程序上下文中初始化太复杂

您可以在我所有的Spring MVC应用程序示例中看到这两个缺点。 例如,您可以打开我关于CNVR的Spring REST服务的最新教程之一 。 看一下两个类: WebAppConfigInitializer

WebAppConfig

第一个代表本文的第一点。 绝对我需要做一些事情来逻辑上拆分bean配置。 为了解决此问题,我决定执行两个步骤:

  1. 将数据库配置移到单独的类中
    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories("com.mobapp.repository")
    public class DataBaseConfig {private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";private static final String PROPERTY_NAME_DATABASE_URL = "db.url";private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";@Resourceprivate Environment env;@Beanpublic DataSource dataSource() {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));return dataSource;}@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactory() {LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();entityManagerFactoryBean.setDataSource(dataSource());entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));entityManagerFactoryBean.setJpaProperties(hibProperties());return entityManagerFactoryBean;}private Properties hibProperties() {Properties properties = new Properties();properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));return properties;        }@Beanpublic JpaTransactionManager transactionManager() {JpaTransactionManager transactionManager = new JpaTransactionManager();transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());return transactionManager;}}
  2. 在主配置类中转换WebAppConfig类,并通过@Import批注将其余的配置类(在当前情况下仅为DataBaseConfig类)分配给它。
    @Configuration
    @EnableWebMvc
    @Import({DataBaseConfig.class})
    @ComponentScan("com.mobapp")
    @PropertySource("classpath:application.properties")
    public class WebAppConfig extends WebMvcConfigurerAdapter {@Resourceprivate Environment env;@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");}@Overridepublic void configureContentNegotiation(ContentNegotiationConfigurer configurer) {configurer.favorPathExtension(true).useJaf(false).ignoreAcceptHeader(true).mediaType("html", MediaType.TEXT_HTML).mediaType("json", MediaType.APPLICATION_JSON).defaultContentType(MediaType.TEXT_HTML);}@Beanpublic ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {List< ViewResolver > resolvers = new ArrayList< ViewResolver >();InternalResourceViewResolver r1 = new InternalResourceViewResolver();r1.setPrefix("/WEB-INF/pages/");r1.setSuffix(".jsp");r1.setViewClass(JstlView.class);resolvers.add(r1);JsonViewResolver r2 = new JsonViewResolver();resolvers.add(r2);ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();resolver.setViewResolvers(resolvers);resolver.setContentNegotiationManager(manager);return resolver;}/*** View resolver for returning JSON in a view-based system. Always returns a* {@link MappingJacksonJsonView}.*/public class JsonViewResolver implements ViewResolver {public View resolveViewName(String viewName, Locale locale)throws Exception {MappingJacksonJsonView view = new MappingJacksonJsonView();view.setPrettyPrint(true);return view;}}}

    这样,您可以将单个大型配置类分为几个较小的类,这些类将包含针对它们的特定配置。

初始化器

在上面提到的示例中, Initializer类的代码过于冗长,并提供了指向其的链接。 我在那里注册了Web应用程序的根配置,映射和过滤器。 如何减少代码行数? 我在AbstractAnnotationConfigDispatcherServletInitializer类上找到了答案。 查看该类,您会注意到它实现了WebApplicationInitializer接口,我在上一版本的Initializer类中已实现了该接口。 所以这是Initializer的新版本:

public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Class< ? >[] getRootConfigClasses() {return null;}@Overrideprotected Class< ? >[] getServletConfigClasses() {return new Class< ? >[] { WebAppConfig.class };}@Overrideprotected String[] getServletMappings() {return new String[] { "/" };}@Overrideprotected Filter[] getServletFilters() {return new Filter[] { new HiddenHttpMethodFilter() };}}

由于这两个步骤,我使Spring MVC应用程序的配置更加优雅。 现在您也可以这样做。 祝好运

参考: Spring:在Fruzenshtein的Notes博客上,与我们的JCG合作伙伴 Alexey Zvolinskiy一起使基于Java的配置更加优雅 。

翻译自: https://www.javacodegeeks.com/2013/11/spring-make-your-java-based-configuration-more-elegant.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366371.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用观察者模式编写一个可被其他对象拓展复用自定义事件系统

观察者模式 定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都将得到通知 什么是观察者模式&#xff1f; 发布—订阅模式又叫观察者模式&#xff0c;它定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态…

布局定位

布局与定位 摆放元素 1&#xff0c;使用流 流实际上就是浏览器在页面上摆放HTML元素所用的方法。浏览器从HTML文件最上面开始&#xff0c;从上到下沿着元素流逐个显示所遇到的各个元素。 每个块元素会按它在HTML标记中出现的顺序放置在页面上。每个新的块元素会带来一个换行。并…

T - Memory and Trident CodeForces - 712B( 注意:* ++ = 的优先级

题意&#xff1a;有四种命令&#xff1a;U代表上移一个单位&#xff0c;D代表下移一个单位&#xff0c;R代表右移一个单位&#xff0c;L代表左移一个单位。 现在给出一串命令&#xff0c;问怎样修改命令中的任意一条命令&#xff0c;使得命令结束后重新返回原点&#xff0c;并且…

python语言精通_Python语言基础从入门到精通

1、python关键字False await else import passNone break except in raiseTrue class finally is returnand continue for lambda tryas def from nonlocal whileassert del global not withasync elif if or yield2、命令行参数williamdeMBP-2:~ william$ python -c "imp…

休眠事实:了解刷新操作顺序很重要

Hibernate将开发人员的思维方式从思考SQL转变为思考对象状态转换。 根据Hibernate Docs&#xff0c;实体可能处于以下状态之一&#xff1a; new / transient&#xff1a;实体不与持久性上下文关联&#xff0c;因为它是数据库不知道的新创建的对象。 持久性&#xff1a;实体与…

[HNOI2012]排队

题目描述 某中学有 n 名男同学&#xff0c;m 名女同学和两名老师要排队参加体检。他们排成一条直线&#xff0c;并且任意两名女同学不能相邻&#xff0c;两名老师也不能相邻&#xff0c;那么一共有多少种排法呢&#xff1f;&#xff08;注意&#xff1a;任意两个人都是不同的&a…

声速的测量的实验原理和应用_声速的测定实验报告心得体会

测量声速的实验报告1。提出问题如何测出声音的速度?2。猜想与假设如果在一定距离内听到声音要多少时间?3。实验步骤步骤应该就是实施实验&#xff0c;第三是实验器材的话&#xff0c;就是要秒表。4。实施实验在一个山谷中&#xff0c;站在距离峭壁680M的地方大叫一声&#xf…

FreeNAS:创建 CIFS 共享(权限)

第一部分&#xff1a;新建账户与指定数据集权限 简单起见&#xff0c;本教程主要介绍带基本身份验证的 CIFS 共享&#xff0c;即只有输入正确的用户名和密码才可以访问共享目录。关于创建匿名共享、多用户权限管理以及域控制器相关内容&#xff0c;我们会另外发布教程专门介绍。…

使用序列化查找对象中的脏字段

假设您正在开发一个将对象自动保存到数据库中的框架。 您需要检测两次保存之间所做的更改&#xff0c;以便仅保存修改过的字段。 如何检测脏场。 最简单的方法是遍历原始数据和当前数据&#xff0c;并分别比较每个字段。 代码如下&#xff1a; public static void getDirtyFie…

js操作table中tr的顺序,实现上移下移一行的效果

总体思路是在table外部加个div&#xff0c;修改div的innerHtml实现改变tr顺序的效果 具体思路是 获取当前要移动tr行的rowIndex&#xff0c;在table中删除掉&#xff0c;然后循环table的rows&#xff0c;到了目标行再直接加进去&#xff0c;最后把整体的html赋值给div完成效果…

oracle日记账单据编号未生成_商管财务数据平台Oracle与共享未付池差异如何核对、解决?...

‍‍近期&#xff0c;总部新上线财务数据平台啦&#xff01;各个系统间的差异异常数据清晰可见&#xff0c;随时可查&#xff0c;今天就和小伙伴们一起分享一下Oracle与共享未付池差异如何核对、解决。首先&#xff0c;将Oracle与共享未付池差异数据导出。由于导出的数据包括本…

python (六)函数

一、函数的形成 需求1&#xff1a;来测试一下‘hello word’ 的长度 # 在没有函数的时候&#xff0c;我们可以用for循环实现 s1 "hello world" length 0 for i in s1:length length1 print(length) 再增加一个需求2&#xff1a;再来测试一下另外一个字符串的长度&…

Java方法中的参数太多,第4部分:重载

期望将过多的参数传递给Java方法的问题之一是&#xff0c;该方法的客户端很难确定它们是否以适当的顺序传递了适当的值。 在以前的文章中&#xff0c;我描述了如何使用自定义类型 &#xff0c; 参数对象和构建器来解决此问题。 解决此问题的另一种方法&#xff08;也是本文的主…

android paint 圆角 绘制_[BOT] 一种android中实现“圆角矩形”的方法

内容简介文章介绍ImageView(方法也可以应用到其它View)圆角矩形(包括圆形)的一种实现方式&#xff0c;四个角可以分别指定为圆角。思路是利用“Xfermode Path”来进行Bitmap的裁剪。背景圆角矩形实现的方法应该很多&#xff0c;网上一大堆。很怀疑为啥安卓的控件不内置这样的属…

解决高度塌陷问题

所谓高度塌陷就是在文档流中&#xff0c;父元素的高度默认是被子元素撑开的&#xff0c;也就是子元素多高&#xff0c;父元素就多高。但是当为子元素设置浮动以后&#xff0c;子元素会完全脱离文档流&#xff0c;此时将会导致子元素无法撑起父元素的高度&#xff0c;导致父元素…

HDU2035 - 人见人爱A^B

求A^B的最后三位数表示的整数。 说明&#xff1a;A^B的含义是“A的B次方” Input 输入数据包含多个测试实例&#xff0c;每个实例占一行&#xff0c;由两个正整数A和B组成&#xff08;1<A,B<10000&#xff09;&#xff0c;如果A0, B0&#xff0c;则表示输入数据的结束&…

Cisco TrustSec(理解)

1、Cisco TrustSec的限制当指定了无效的设备ID时&#xff0c;受保护的访问凭据&#xff08;Protected access credential&#xff0c;PAC&#xff09;设置将失败并保持挂起状态。 即使在清除PAC并配置正确的设备ID和密码后&#xff0c;PAC仍然会失败。作为解决方法&#xff0c;…

Java 8仍然需要LINQ吗? 还是比LINQ更好?

长期以来&#xff0c; LINQ是.NET软件工程生态系统中发生的最好的事情之一。 通过在Visual Studio 2008中引入lambda表达式和monads &#xff0c;它使C&#xff03;语言比Java&#xff08;当时的版本6&#xff09;更先进&#xff0c;并且仍在讨论泛型类型擦除的优缺点。 这项成…

web前端(12)—— 页面布局2

本篇博文&#xff0c;主要就讲定位的问题&#xff0c;也就是页面布局里最重要的&#xff0c;本篇博文不出意外的话&#xff0c;也是css的最后一篇博文了 定位&#xff0c;position属性 定位有三种&#xff1a; 相对定位绝对定位固定定位 相对定位&#xff0c;position&#x…

51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

题目链接 \(Description\) 给定一棵树。每次询问给定\(a\sim b,c\sim d\)两个下标区间&#xff0c;从这两个区间中各取一个点&#xff0c;使得这两个点距离最远。输出最远距离。\(n,q\leq10^5\)。 \(Solution\) 一个集合直径的两端点&#xff0c;在被划分为两个集合后一定是两个…