- 浏览: 333099 次
- 性别:
- 来自: 天津
文章分类
最新评论
-
xing0029:
这样配置的话 事物不成功啊 还有什么地方需要注意的么 可以加我 ...
JTA集成JOTM或Atomikos配置分布式事务(Tomcat应用服务器) -
mengqingyu:
liuxiaolu 写道jotm的我的没有成功,楼主能否帮助一 ...
JTA集成JOTM或Atomikos配置分布式事务(Tomcat应用服务器) -
liuxiaolu:
jotm的我的没有成功,楼主能否帮助一下
JTA集成JOTM或Atomikos配置分布式事务(Tomcat应用服务器) -
aptech406328627:
求解救,没弄好QQ:1053942353
Spring邮件发送(可带附件,模板,群发,异步发送等功能) -
ghpaas:
web可视化自定义表单推荐使用GForms开发平台(http: ...
在线表单设计器设计原理
Spring扩展点
1.IOC生成类全名
2.转换生成映射的URL大小写
3.参数自定义类型转换
4.自定义异常拦截器
1.IOC生成类全名
<!-- 自动扫描且只扫描@Controller --> <context:component-scan base-package="cn.com.demo.**.controller" name-generator="cn.com.demo.framework.spring.context.annotation.FullNameBeanNameGenerator" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
public class FullNameBeanNameGenerator extends AnnotationBeanNameGenerator{ @Override protected String buildDefaultBeanName(BeanDefinition definition) { return definition.getBeanClassName(); } }
2.转换生成映射的URL大小写
<!-- 通过 @Controller 和 @RequestMapping 从url定位到类的方法, 自定义CoC实现, 不要再配置annotation-driven --> <bean class="cn.com.demo.framework.web.springmvc.support.CocRequestMappingHandlerMapping"> <property name="basePackage" value="cn.com.demo" /> </bean>
public class CocRequestMappingHandlerMapping extends RequestMappingHandlerMapping{ /** Controller类的后缀 */ private static final String CONTROLLER_SUFFIX = "Controller"; /** 映射url路径的根 */ private String basePackage; //父类的属性 private boolean useSuffixPatternMatch = true; private boolean useTrailingSlashMatch = true; private final List<String> fileExtensions = new ArrayList<String>(); /** * Look for handler methods in a handler. * @param handler the bean name of a handler or a handler instance */ protected void detectHandlerMethods(final Object handler) { //Assert.notNull(this.basePackage, "must config basePackage!"); super.detectHandlerMethods(handler); } /** * 这个只改了createRequestMappingInfo的调用,增加了参数 * Uses method and type-level @{@link RequestMapping} annotations to create * the RequestMappingInfo. * * @return the created RequestMappingInfo, or {@code null} if the method * does not have a {@code @RequestMapping} annotation. * * @see #getCustomMethodCondition(Method) * @see #getCustomTypeCondition(Class) */ @Override protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { RequestMappingInfo info = null; RequestMapping methodAnnotation = AnnotationUtils.findAnnotation(method, RequestMapping.class); if (methodAnnotation != null) { RequestCondition<?> methodCondition = getCustomMethodCondition(method); info = createRequestMappingInfo(methodAnnotation, methodCondition, method, handlerType); RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class); if (typeAnnotation != null) { RequestCondition<?> typeCondition = getCustomTypeCondition(handlerType); info = createRequestMappingInfo(typeAnnotation, typeCondition, method, handlerType).combine(info); } } return info; } /** * 将父类同名方法加入controller的类型和方法参数 */ private RequestMappingInfo createRequestMappingInfo(RequestMapping annotation, RequestCondition<?> customCondition, Method method, Class<?> handlerType) { String[] patterns = resolveEmbeddedValuesInPatterns(annotation.value()); //@RequestMapping没有配置value, 加入coc部分 if( patterns.length==0 ){ StringBuilder p = new StringBuilder(); if (this.basePackage != null) { String packageName = ClassUtils.getPackageName(handlerType); if (packageName.startsWith(this.basePackage)) { String subPackage = packageName.substring(this.basePackage.length()).replace('.', '/'); if( subPackage.endsWith("/controller") ){ //去掉/backup/controller的 /controller subPackage = subPackage.substring(0,subPackage.indexOf("/controller")); } p.append(subPackage.toLowerCase()); p.append("/"); } } //类名去掉后缀小写 String className = handlerType.getSimpleName(); className = (className.endsWith(CONTROLLER_SUFFIX) ? className.substring(0, className.lastIndexOf(CONTROLLER_SUFFIX)) : className); p.append(className.toLowerCase()).append("/");//类名小写 p.append(method.getName().toLowerCase());//方法名小写 patterns = new String[]{p.toString()}; } return new RequestMappingInfo( new PatternsRequestCondition(patterns, getUrlPathHelper(), getPathMatcher(), this.useSuffixPatternMatch, this.useTrailingSlashMatch, this.fileExtensions), new RequestMethodsRequestCondition(annotation.method()), new ParamsRequestCondition(annotation.params()), new HeadersRequestCondition(annotation.headers()), new ConsumesRequestCondition(annotation.consumes(), annotation.headers()), new ProducesRequestCondition(annotation.produces(), annotation.headers(), getContentNegotiationManager()), customCondition); } //----------------------set get public void setBasePackage(String basePackage) { this.basePackage = basePackage; } public void setUseSuffixPatternMatch(boolean useSuffixPatternMatch) { this.useSuffixPatternMatch = useSuffixPatternMatch; } public void setUseTrailingSlashMatch(boolean useTrailingSlashMatch) { this.useTrailingSlashMatch = useTrailingSlashMatch; } }
3.参数自定义类型转换
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer"> <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="conversionService"> <bean class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="cn.com.demo.framework.spring.core.convert.converter.StringToDateConverter"/> </list> </property> </bean> </property> </bean> </property> <property name="customArgumentResolvers"> <list> <bean class="cn.com.demo.framework.web.springmvc.support.method.support.crud.CrudHandlerMethodArgumentResolver"/> </list> </property> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8" /> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="serializers"> <array> <bean class="cn.com.demo.canyin.common.springmvc.converter.json.LongToStringJsonSerializer" /> </array> </property> <property name="dateFormat"> <bean class="java.text.SimpleDateFormat"> <constructor-arg value="yyyy-MM-dd'T'HH:mm:ss.SSS" /> </bean> </property> </bean> </property> </bean> <bean class="org.springframework.http.converter.ResourceHttpMessageConverter" /> </list> </property> </bean>
public class StringToDateConverter implements Converter<String, Date>{ @Override public Date convert(String source) { if( source==null || source.length()==0 ) return null; int length = source.length(); switch (length) { case 5: return parse("HH:mm", source); case 10: return parse("yyyy-MM-dd", source); case 19: case 21: case 22: return parse("yyyy-MM-dd HH:mm:ss", source); case 23: return parse("yyyy-MM-dd'T'HH:mm:ss.SSS", source); case 28: try { return new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy", Locale.US).parse(source); } catch (ParseException e) { throw new RuntimeException("时间转换格式异常,datestr:" + source, e); } default: throw new RuntimeException("Unsupport Date Format: " + source); } } /** * 解析date */ private Date parse(String format, String date){ try { return new SimpleDateFormat(format).parse(date); } catch (ParseException e) { throw new RuntimeException(e); } } } public class CrudHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver{ @Override public boolean supportsParameter(MethodParameter parameter) { Class<?> paramType = parameter.getParameterType(); return QueryParam.class.isAssignableFrom(paramType); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { Class<?> paramType = parameter.getParameterType(); //查询参数 QueryParam p = parseQueryParam(parameter, webRequest); return p; } /** * <b>功能描述:</b>解析查询参数<br> */ @SuppressWarnings("serial") private QueryParam parseQueryParam(MethodParameter parameter, NativeWebRequest webRequest){ QueryParam p = new QueryParam(); //分页参数 p.setStart(getInteger(webRequest, "start")); p.setLimit(getInteger(webRequest, "limit")); String sort = webRequest.getParameter("sort"); if(StringUtils.isNotBlank(sort)){ SortExpression[] orderBy = JsonConverterUtils.getJc().fromJson(sort, SortExpression[].class); DefaultConvertName dcn = new DefaultConvertName(); orderBy[0].setProperty(dcn.convertToColumnName(orderBy[0].getProperty())); p.setSort(orderBy[0].toSqlString()); } return p; } /** * 获取整数参数 */ private Integer getInteger(NativeWebRequest webRequest, String name){ String p = webRequest.getParameter(name); if( p==null || p.length()==0 ) return null; return Integer.valueOf(p); } /** * 如果是get方法, 编码参数 */ private String encodeParameter(NativeWebRequest webRequest, String paramName){ HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); String p = webRequest.getParameter(paramName); if( "GET".equalsIgnoreCase(request.getMethod())){ return RequestUtil.encodeParameter(p); } return p; } } public class LongToStringJsonSerializer extends JsonSerializer<Long> { @Override public Class<Long> handledType() { return Long.class; } @Override public void serialize(Long value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(value.toString()); } }
4.自定义异常拦截器
<!-- mvc exception handler --> <bean id="handlerExceptionResolver" class="cn.com.demo.framework.enterprise.spring.web.ProjectHandlerExceptionResolver"></bean>
public class ProjectHandlerExceptionResolver implements HandlerExceptionResolver{ private final Logger logger = LoggerFactory.getLogger(getClass()); /** json 转换 */ @Resource private JsonConverter jsonConverter; @Resource private LogManageService logManageService; @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { return null; } /** * <b>功能描述:</b> * 是否ExtForm的StandardSubmit模式<br> * 前台需要额外传入X-Requested-With的参数来说明本次提交为StandardSubmit */ private boolean isExtFormStandardSubmit(HttpServletRequest request){ return request.getParameter("X-Requested-With")!=null; } }
发表评论
-
Spring AOP动态代理
2015-01-25 22:23 790package com.test.dynamicproxy; ... -
Spring加载资源并装配对象的过程
2015-01-25 22:20 10601. 定义好Spring的配置文件。 2. 通过Resourc ... -
(转载)Spring Bean 初始化过程
2013-05-10 13:10 1155Spring 的几个接口 1.InitializingBea ... -
(转载)浅谈Spring事务隔离级别
2013-04-15 14:45 980一、Propagation : key属 ... -
AOP+LOG4J日志框架(自定义注解)
2013-04-11 15:00 2750工作中用到日志功能,参考网上一些资料,写了个比较通用的日志框架 ... -
(转载)spring AOP获得session
2013-02-20 17:01 2421由于Spring 的AOP面向切面编程,与Servlet容器没 ... -
Quartz(三)原理及源码分析
2012-10-30 14:56 14049quartz配置文件中可以通过以下两种配置读取方式 org.q ... -
spring-security3(二)源码分析
2012-04-06 17:08 8190利用断点走了一遍spring-security源码的核心部分, ... -
spring-security3(一)配置详解及API扩展(包含ajax返回)
2012-04-06 17:05 3818最近对spring-security3做了一些初步了解,搜集了 ... -
AOP+Ehcache 缓存框架
2011-12-14 16:49 1680AOP+Ehcache 实现缓存功能 设计思路:查询数据,通 ... -
JTA集成JOTM或Atomikos配置分布式事务(Tomcat应用服务器)
2010-01-15 21:01 6666一.以下介绍Spring中直接集成JOTM提供JTA事务管理、 ... -
Quartz(二)整合Spring容器中bean及动态调度任务
2010-01-13 10:01 7733Quartz 是开源任务调度框架中的翘首,它提供了强大任务 ... -
Quartz(一)在Spring中设置动态定时任务
2009-05-17 07:09 7808什么是动态定时任务: 是由客户制定生成的,服务端只知道该去执行 ... -
Spring邮件发送(可带附件,模板,群发,异步发送等功能)
2009-05-17 06:27 8733以下是我对spring发送邮件的总结: 分别使用了两种方法:单 ...
相关推荐
这个压缩包提供的"spring扩展点测试示例代码"是一个实例,帮助我们理解如何在实践中利用Spring的扩展点进行自定义功能的实现。 首先,Spring的核心设计理念之一就是“依赖注入”(Dependency Injection,DI),它...
Spring常用注解和扩展点,Spring常用注解和扩展点,Spring常用注解和扩展点,Spring常用注解和扩展点,Spring常用注解和扩展点,Spring常用注解和扩展点,Spring常用注解和扩展点,Spring常用注解和扩展点
3. **Spring AOP**:面向切面编程模块,允许我们定义“切面”,这些切面可以在程序运行时插入到其他对象的执行流程中,实现如日志、事务管理等跨切面关注点。 4. **Spring MVC**:模型-视图-控制器架构,是Spring...
在Spring框架中,扩展点是允许用户自定义行为的关键组件,而`NamespaceHandler`就是其中的一个重要扩展点,主要用于处理自定义的XML命名空间。当我们需要在Spring配置文件中引入自定义标签时,`NamespaceHandler`起...
本文主要探讨Spring扩展原理,特别是`BeanFactoryPostProcessor`、`BeanDefinitionRegistryPostProcessor`以及`ApplicationListener`这三种核心扩展点。 首先,`BeanFactoryPostProcessor`是Spring IOC容器中的一种...
《Spring应用扩展》 在Spring框架中,应用扩展是一个重要的概念,它涉及到Spring的灵活性和可配置性。扩展Spring的应用通常包括对配置的拓展、Bean的作用域管理以及依赖注入的实现方式。以下将详细讲解这些知识点。...
在Spring 3.0.5版本中,Spring扩展了对AOP的支持,特别是在处理HTTP响应时,可以通过AOP来获取`HttpServletResponse`对象。`HttpServletResponse`是Servlet API中的核心接口,它用于封装服务器向客户端发送的响应...
本文将深入探讨如何在Spring框架中利用Java注解进行扩展,以提升代码的可读性和可维护性。 首先,我们需要了解Java注解(Annotation)。注解是Java语言的一种元数据,它提供了在编译时或运行时对代码进行信息附加的...
Springboot启动扩展点是Spring框架的核心思想,容器refresh的时候,外部看上去风平浪静,其实内部则是一片惊涛骇浪,汪洋一片。Springboot更是封装了Spring,遵循约定大于配置,加上自动装配的机制。很多时候我们...
扩展点集合存放 Spring 扩展点(主要是 BeanFactoryPostProcessor、BeanPostProcessor)接口的 list 集合。 除了了解 Spring Context 的组成部分外,我们还需要了解它的生命周期。Spring Context 的生命周期主要...
Spring框架与LDAP(轻量级目录访问协议)的结合使用,可以实现高效的单点登录(Single Sign-On,简称SSO)系统。SSO允许用户在多个应用系统中只需要登录一次,即可访问所有相互信任的应用系统,提高了用户体验并简化...
在微服务架构中,Spring Security 可以帮助我们保护每个微服务的入口点,确保只有经过验证的用户才能访问受保护的资源。 整合Spring Security到Spring Cloud Gateway的过程通常包括以下步骤: 1. **配置Redis**:...
Spring Boot是Spring框架的一个重要扩展,它提供了一种快速配置的方式来简化新Spring应用的初始搭建以及开发过程。它包含了一系列默认配置来帮助开发者快速开始项目,并且支持自动配置特性,能够自动配置Spring应用...
7. **Spring Aspects**:此模块提供了AOP的扩展,支持自定义切面和通知类型,增强了Spring的面向切面编程能力。 8. **Spring WebFlux**:对于反应式编程,Spring WebFlux提供了非阻塞的Web开发模型,适用于高并发和...
BeanFactoryPostProcessor接口是Spring提供的一种扩展点,它允许在容器实例化相应对象之前,对注册到容器的BeanDefinition所保存的信息做一些额外的操作,例如修改bean定义的某些属性或者增加其他信息等。...
* AOP(Aspect-Oriented Programming): Spring使用AOP来实现面向方面的编程,提高系统的可维护性和可扩展性。 2. Spring核心概念 Spring的核心概念包括: * Bean:Spring中的Bean是指一个 Java对象,Bean可以...
另外,Spring Cloud扩展了Spring Boot的功能,提供了服务发现、负载均衡、配置中心等一系列微服务相关的工具,为构建大规模分布式系统提供了便利。 Spring框架还包含对消息处理的支持,如Spring AMQP,它提供了对...
《Spring 揭秘:全面深入了解Spring》是一本旨在帮助开发者深入理解并熟练掌握Spring框架的权威指南。...通过阅读这本书,你将能够深入理解Spring的内部机制,更好地利用Spring来构建高效、可扩展的企业级应用。
下面是对 Spring Framework 的详细知识点总结: 1. 什么是 Spring? Spring 是一个基于 Java 的开源框架,提供了一个通用的编程模型和配置机制,帮助开发者快速构建企业级应用程序。Spring 的主要特点是轻量级、...