- 浏览: 1236787 次
- 性别:
- 来自: 广州
-
文章分类
- 全部博客 (883)
- Spring (101)
- Swing (1)
- Mysql (21)
- Js (59)
- Jsp (2)
- Hibernate (19)
- Myeclipse (5)
- SqlServer 2000 (2)
- poi (15)
- Java (70)
- SSH (12)
- Html (47)
- Fusion Charts (1)
- C\C++ (2)
- 汇编 (36)
- Jquery (37)
- Struts2 (6)
- Ubuntu (16)
- powerDesinger (4)
- Jboss (3)
- JAX-RS (13)
- JAXB (5)
- JAX-WS (11)
- JMS (4)
- WebSocket (8)
- PHP (16)
- Flash (1)
- maven (3)
- Oracle (8)
- HttpClient (6)
- sqlserver (19)
- svn (5)
- Tomcat (3)
- Jdbc (3)
- EsayUi (11)
- 微信公众平台 (19)
- IIS (2)
- Freemarker (11)
- Comet (1)
- Spring MVC (85)
- JBoss Seam (3)
- 二维码 (9)
- Spring Security (4)
- Ehcache (3)
- Apache Shiro (7)
- jackson (16)
- JPA (8)
- jcaptcha (2)
- RSA (2)
- Ajax (6)
- 跟我学Shiro (0)
- Spring4 (19)
- 跟我学spring3 (0)
- css (32)
- excel (4)
- Filter (3)
- 微信公众帐号开发教程 (0)
- Android (6)
- log4j (6)
- 淘宝接口 (17)
- 支付集成 (3)
- 单点登录 (3)
- Html5 (27)
- 移动平台前端 (3)
- Linux (44)
- FusionCharts (27)
- Json Jackson Xml (5)
- 方培工作室-微信开发 (0)
- Apache与Tomcat与IIS整合 (10)
- Nginx (17)
- webService (2)
- apache (4)
- lucene (3)
- lodop (2)
- Shiro (3)
- zTree (2)
- ireport (12)
- Servlet3.0 (5)
- 前端美工 (19)
- AngularJS (1)
- C#开发微信门户及应用 (0)
- Shell (3)
- bat脚本 (16)
- Bootstrap (26)
- Less (10)
- photoshop (6)
- Redis (6)
- Mongodb (10)
- MyBatis (3)
- 数据结构 (0)
- 读写分离-主从复制 (0)
- JFinal (0)
- 百度地图api (3)
- hadoop-hbase-hive-spark (3)
- WebStorm (2)
- Quartz (5)
- ios (0)
- Mina (8)
- Android Studio (4)
- Ratchet教程 (0)
- 移动端重构系列 (1)
- cubic-bezier贝塞尔曲线CSS3动画工具 (1)
- nginx+tomcat+memcached集群 (0)
- 集群 (0)
- ZooKeeper (3)
- Dubbo (0)
- vpn (0)
- kafka (0)
- JVM垃圾回收机制 (0)
- 微信小程序 (0)
- Lua (0)
- Hystrix (0)
- Vue.js (0)
- mycat (0)
- Openresty (0)
- springBoot (0)
- 新分类 (0)
- guava (0)
- 大数据 (0)
- Sentinel (0)
最新评论
-
JackMacing:
中文怎么解决?
SpringMVC与iReport(JasperReports) 5.6整合开发实例 -
18335864773:
用pageoffice把.可以实现在线的文档操作.直接转pdf ...
转:使用jasperreport动态生成pdf,excel,html -
linhao0907:
推荐一款轻量开源的支付宝组件:https://github.c ...
关于Alipay支付宝接口(Java版) -
songronghu:
太好了,非常有用,谢谢分享~
Java ConcurrentModificationException 异常分析与解决方案 -
wzwahl36:
http://www.atool.org/json2javab ...
Java下利用Jackson进行JSON解析和序列化
很久之前写过两篇博客:
spring3.0使用annotation完全代替XML
spring3.0使用annotation完全代替XML(续)
用java config来代替XML,当时还遗留下一些问题:
先来说说web.xml,有两种方法来替代
(一)annotation
servlet3.0增加了@WebServlet, @WebFilter, @WebListener等注解,servlet容器会在classpath扫描并注册所有的标注好的servlet, filter和listener。这种方法只针对你能访问源代码的情况,对于像spring_mvc用到的DispatcherServlet,无法在源码上加annotation,可以用第二种方法来实现bootstrap
(二)ServletContainerInitializer
这是servlet3的一个接口,我们来看看spring-web提供的实现
@HandlesTypes也是servlet3中的注解,这里它处理的是WebApplicationInitializer,也就是说servlet容器会扫描classpath,将所有实现了WebApplicationInitializer接口的类传给onStartup方法中的webAppInitializerClasses,并调用onStartup方法来注册servlet。具体的注册代码可以这样写:
以上的代码分别调用了sc.addFilter, sc.addListener, sc.addServlet来注册filter, listener和servlet.
用以上的方法就能将WEB-INF/web.xml删除了.spring3.1.M2开始增加了一系列annotation来实现声明性事务及简化spring_mvc配置。WebInit中注册的DispatcherServlet所对应的配置在septem.config.web包里面:
一行@EnableWebMvc就导入了spring_mvc需要的诸多bean,再配合@ComponentScan扫描septem.controller包里面所有的@Controller,基本的mvc配置就完成了。
声明性事务也是类似,通过spring root application context扫描包septem.config.app:
DataConfig定义了所有与数据库和hibernate相关的bean,通过@EnableTransactionManagement实现声明性事务。
service是如何注册的呢?
通过@ComponentScan扫描包septem.service里定义的所有service,一个简单service实现如下:
这样整个项目中就没有XML文件了。在写这些代码的过程中也碰到不少问题,纪录如下:
(一)项目没有web.xml,maven的war插件要加上failOnMissingWebXml=false
(二) tomcat-embeded7.0.16还有点小BUG,不能把DispatcherServlet映射为"/",所以代码里把它映射为"/s3/"
(三) 如果要使用spring提供的OpenSessionInViewFilter,在定义Hibernate SessionFactory的时候,不能直接new SessionFactory出来,即以下代码是不能实现声明性事务的:
必须使用spring提供的FactoryBean:
后记:在spring3.1以servlet3中annotation已经是一等公民了,可以实现任何原先只能在xml文件中配置的功能,并具有简洁,静态检查及重构友好等优点。总体上来讲spring提供的“魔法”还是太多了,尤其是跟hibernate,事务,open session in view等机制结合在一起的时候,简洁代码的背后隐藏着太多的依赖关系,如果程序出了问题,排除这些魔法,一层一层地还原程序的本来面目,将是一件很需要耐心的事情
spring3.0使用annotation完全代替XML
spring3.0使用annotation完全代替XML(续)
用java config来代替XML,当时还遗留下一些问题:
- <tx:annotation-driven />声明性事务等配置无法用简单代码来实现
- web.xml无法去掉
先来说说web.xml,有两种方法来替代
(一)annotation
@WebServlet(urlPatterns="/hello") public class HelloServlet extends HttpServlet {}
servlet3.0增加了@WebServlet, @WebFilter, @WebListener等注解,servlet容器会在classpath扫描并注册所有的标注好的servlet, filter和listener。这种方法只针对你能访问源代码的情况,对于像spring_mvc用到的DispatcherServlet,无法在源码上加annotation,可以用第二种方法来实现bootstrap
(二)ServletContainerInitializer
这是servlet3的一个接口,我们来看看spring-web提供的实现
@HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer { public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException { //implemention omitted } }
@HandlesTypes也是servlet3中的注解,这里它处理的是WebApplicationInitializer,也就是说servlet容器会扫描classpath,将所有实现了WebApplicationInitializer接口的类传给onStartup方法中的webAppInitializerClasses,并调用onStartup方法来注册servlet。具体的注册代码可以这样写:
public class WebInit implements WebApplicationInitializer { @Override public void onStartup(ServletContext sc) throws ServletException { sc.addFilter("hibernateFilter", OpenSessionInViewFilter.class).addMappingForUrlPatterns(null, false, "/*"); // Create the 'root' Spring application context AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.scan("septem.config.app"); // Manages the lifecycle of the root application context sc.addListener(new ContextLoaderListener(root)); AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext(); webContext.setConfigLocation("septem.config.web"); ServletRegistration.Dynamic appServlet = sc.addServlet("appServlet", new DispatcherServlet(webContext)); appServlet.setLoadOnStartup(1); appServlet.addMapping("/"); } }
以上的代码分别调用了sc.addFilter, sc.addListener, sc.addServlet来注册filter, listener和servlet.
用以上的方法就能将WEB-INF/web.xml删除了.spring3.1.M2开始增加了一系列annotation来实现声明性事务及简化spring_mvc配置。WebInit中注册的DispatcherServlet所对应的配置在septem.config.web包里面:
@Configuration @ComponentScan(basePackages="septem.controller") @EnableWebMvc public class WebConfig { }
一行@EnableWebMvc就导入了spring_mvc需要的诸多bean,再配合@ComponentScan扫描septem.controller包里面所有的@Controller,基本的mvc配置就完成了。
声明性事务也是类似,通过spring root application context扫描包septem.config.app:
@Configuration @EnableTransactionManagement public class DataConfig { @Bean public AnnotationSessionFactoryBean sessionFactory() { AnnotationSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource()); sessionFactoryBean.setNamingStrategy(new ImprovedNamingStrategy()); sessionFactoryBean.setPackagesToScan("septem.model"); sessionFactoryBean.setHibernateProperties(hProps()); return sessionFactoryBean; } private DataSource dataSource() { BasicDataSource source = new BasicDataSource(); source.setDriverClassName("org.hsqldb.jdbcDriver"); source.setUrl("jdbc:hsqldb:mem:s3demo_db"); source.setUsername("sa"); source.setPassword(""); return source; } @Bean public HibernateTransactionManager transactionManager() { HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager(); hibernateTransactionManager.setSessionFactory(sessionFactory().getObject()); return hibernateTransactionManager; } private Properties hProps() { Properties p = new Properties(); p.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); p.put("hibernate.cache.use_second_level_cache", "true"); p.put("hibernate.cache.use_query_cache", "true"); p.put("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider"); p.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache.xml"); p.put("hibernate.show_sql", "true"); p.put("hibernate.hbm2ddl.auto", "update"); p.put("hibernate.generate_statistics", "true"); p.put("hibernate.cache.use_structured_entries", "true"); return p; } }
DataConfig定义了所有与数据库和hibernate相关的bean,通过@EnableTransactionManagement实现声明性事务。
service是如何注册的呢?
@Configuration @ComponentScan(basePackages="septem.service") public class AppConfig { }
通过@ComponentScan扫描包septem.service里定义的所有service,一个简单service实现如下:
@Service @Transactional public class GreetingService { @Autowired private SessionFactory sessionFactory; @Transactional(readOnly=true) public String greeting() { return "spring without xml works!"; } @Transactional(readOnly=true) public Book getBook(Long id) { return (Book) getSession().get(Book.class, id); } @Transactional(readOnly=true) public Author getAuthor(Long id){ return (Author) getSession().get(Author.class, id); } public Book newBook() { Book book = new Book(); book.setTitle("java"); getSession().save(book); return book; } public Author newAuthor() { Book book = newBook(); Author author = new Author(); author.setName("septem"); author.addBook(book); getSession().save(author); return author; } private Session getSession() { return sessionFactory.getCurrentSession(); } }
这样整个项目中就没有XML文件了。在写这些代码的过程中也碰到不少问题,纪录如下:
(一)项目没有web.xml,maven的war插件要加上failOnMissingWebXml=false
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1.1</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin>
(二) tomcat-embeded7.0.16还有点小BUG,不能把DispatcherServlet映射为"/",所以代码里把它映射为"/s3/"
appServlet.addMapping("/s3/");
(三) 如果要使用spring提供的OpenSessionInViewFilter,在定义Hibernate SessionFactory的时候,不能直接new SessionFactory出来,即以下代码是不能实现声明性事务的:
@Bean public SessionFactory sessionFactory() { org.hibernate.cfg.Configuration config = new org.hibernate.cfg.Configuration(); config.setProperties(hProps()); config.addAnnotatedClass(Book.class); return config.buildSessionFactory(); }
必须使用spring提供的FactoryBean:
@Bean public AnnotationSessionFactoryBean sessionFactory() { AnnotationSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource()); sessionFactoryBean.setNamingStrategy(new ImprovedNamingStrategy()); sessionFactoryBean.setPackagesToScan("septem.model"); sessionFactoryBean.setHibernateProperties(hProps()); return sessionFactoryBean; }
后记:在spring3.1以servlet3中annotation已经是一等公民了,可以实现任何原先只能在xml文件中配置的功能,并具有简洁,静态检查及重构友好等优点。总体上来讲spring提供的“魔法”还是太多了,尤其是跟hibernate,事务,open session in view等机制结合在一起的时候,简洁代码的背后隐藏着太多的依赖关系,如果程序出了问题,排除这些魔法,一层一层地还原程序的本来面目,将是一件很需要耐心的事情
发表评论
-
spring boot整合mybatis+mybatis-plus
2019-02-08 23:58 0https://www.cnblogs.com/lia ... -
Spring点滴 Spring实战系列
2018-11-14 18:06 0https://www.cnblogs.com/si ... -
易百教程
2017-06-07 14:00 0http://www.yiibai.com/lua/l ... -
关于Spring Data redis几种对象序列化的比较
2016-09-06 15:01 0问题 最近在整一个spring data r ... -
spring 结合 Redis 例子,简单入门例子
2016-09-05 10:51 0http://oyhk.iteye.com/blog/ ... -
spring与redis集成之aop整合方案
2016-09-05 10:20 0http://blog.csdn.net/zhann ... -
Dubbo搭建例子
2016-09-03 17:35 0http://blog.csdn.net/lzxads ... -
集群部署服务和消费者测试(1)
2016-09-03 17:10 0修改dp和dc程序为注册到集群zookeeper中 ... -
zookeeper 服务器安装 单例和集群
2016-09-03 17:02 0http://blog.csdn.net/fangxi ... -
dubbo起步搭建Spring+SpringMVC+dubbo的开发环境
2016-09-03 16:49 0http://blog.csdn.net/fangxi ... -
Memcached与Spring AOP构建数分布式据库前端缓存框架
2016-09-02 22:19 0由于上一篇有介绍了Memcached缓存,并集群部 ... -
Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
2016-09-02 22:11 0原文链接:http://blog.csdn.net/cong ... -
重要,Spring注解事务无效 和 Cannot add foreign key constraint
2016-02-20 02:18 0Cannot add foreign key con ... -
Spring2.5.6中定时器Quarz的使用
2015-10-08 10:07 691下面说明详细的配置: applicationContext ... -
spring ioc原理(看完后大家可以自己写一个spring)
2015-08-07 14:43 0http://blog.csdn.net/it_ma ... -
Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
2015-08-04 19:32 0http://jiwenke.iteye.com/ ... -
spring源码分析之——spring aop原理
2015-08-04 19:18 0aop是spring中非常有趣的一个功能。如果应用得当会大有 ... -
自我分析-Spring AOP
2015-08-04 19:13 0aop是spring中非常有趣的一个功能。如果应用得当会大有 ... -
利用AbstractRoutingDataSource实现动态数据源切换
2015-07-15 14:44 0利用AbstractRoutingDataSource实现 ... -
spring 使用AbstractRoutingDataSource自定义动态数据源时的事务处理
2015-07-15 14:38 0spring 使用AbstractRoutingDataSo ...
相关推荐
4. **注解驱动的Spring**:"Spring3.0-annotation"章节会介绍如何利用Java注解来代替XML配置,如`@Component`、`@Service`、`@Repository`和`@Controller`等,这些注解可以帮助我们声明bean及其作用范围。...
- 自Spring 3.0起,可以用Java配置代替XML配置,同样使用`@EnableTransactionManagement`开启事务管理,然后使用`@Transactional`注解。 ```java @Configuration @EnableTransactionManagement public class ...
2. **注解配置 (Annotation-based Configuration)**:Spring 2.5 引入了大量注解,如 `@Autowired`、`@Required` 和 `@Component` 等,使得开发者可以使用注解代替 XML 配置文件,简化了配置过程,提高了开发效率。...
MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录. orm工具的基本思想 无论是用过的hibernate,mybatis,你都可以法相他们有一个...
Spring 3.0引入了基于Java的配置支持,可以通过`@Configuration`注解定义配置类。在配置类中,使用`@Bean`注解的方法来定义Bean实例。这种方式相比于XML配置更加简洁、易于维护。 29. **解释Spring的模板类,如...
- **注解驱动**:用注解(Annotation)代替XML配置,简化了元数据的声明,减少了出错可能,提高了开发效率。 - **依赖注入**:引入了Dependency Injection(DI)概念,替代了传统的JNDI查找机制,使Session Bean的...
例如,我们可以使用`@WebFilter`和`@WebListener`来代替web.xml中的filter和listener元素。 总的来说,Servlet注解配置提供了以下优势: 1. **简洁性**:注解使得配置更加直观,减少了大量XML配置文件的编写。 2. ...