spring实用知识分享
来源:互联网 发布:大尺度耽美网络剧 编辑:程序博客网 时间:2024/06/06 12:35
最近整理了下之前看到的,用过的spring的一些实用知识,特写出来供同学们参考,感觉前人的成果~
spring容器介绍:
1、 spring容器为父容器,springMvc容器为子容器
2、 父容器由ContextLoaderListener加载,子容器由DispatcherServlet加载
3、 子容器可以访问父容器中的bean,但是父容器不可以访问子容器中的bean
注意点:明确容器之间的关系,明白各自配置文件中的内容的作用域
Spring对于静态变量怎么初始化赋值?
很多时候,我们在工作中需要将一些常用配置写入properties配置文件,然后将值赋给一个静态变量供程序调用,spring默认是没有静态变量赋值的,需要我们自己去实现,请看下面2种方法:
方法一:
1、新建静态变量
public class ConstantUtil { // 云OSS公共图片路径(正式路径请用pub_img/,测试路径请用test_pub_img/) public static String OSS_PUB_IMG; // 云OSS 公共图片前缀url public static String OSS_PUB_IMG_URL;}
2、新建配置文件properties,设置静态变量对应的值
3、在spring配置文件中加载配置文件
<!-- 加载配置文件 ,多个用逗号隔开--> <context:property-placeholder location="classpath:properties/antx_admin.properties" />
4、新建一个类实现spring的InitializingBean和ServletContextAware接口
public class SystemInitBean implements InitializingBean, ServletContextAware { public void setOssPubImg(String ossPubImg) { ConstantUtil.OSS_PUB_IMG = ossPubImg; } public void setOssPubImgUrl(String ossPubImgUrl) { ConstantUtil.OSS_PUB_IMG_URL = ossPubImgUrl; } @Override public void setServletContext(ServletContext servletContext) { // TODO Auto-generated method stub } @Override public void afterPropertiesSet() throws Exception { // TODO Auto-generated method stub }}
5、然后在spring配置文件中注入SystemInitBean这个类,将properties的值赋给静态变量
<!-- 初始化antx_admin.properties配置文件中的值到静态变量中 --> <bean class="com.rightknights.web.admin.listener.SystemInitBean"> <property name="ossPubImg" value="${OSS_PUB_IMG}"/> <property name="ossPubImgUrl" value="${OSS_PUB_IMG_URL}"/> </bean>
方法二
1、同上,新建静态变量
2、在spring配置文件中,通过propertiesFactoryBean加载配置文件
<!-- 注意这个id为setting,后面要用到 --> <bean id="setting" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="locations"> <list> <value>classpath:properties/antx_admin.properties</value> </list> </property> <property name="fileEncoding" value="UTF-8"></property> </bean>
3、新建初始化类,并在spring配置文件中配置扫描包
@Componentpublic class ConfigProperty { private static ConfigProperty insstance; public static ConfigProperty getInstance(){ return insstance; } public ConfigProperty(){ insstance = this; } @Value("#{setting['OSS_PATH']}") private String OSS_PATH; @Value("#{setting['DOP_URL']}") private String DOP_URL; public String getOSS_PATH() { return OSS_PATH; } public void setOSS_PATH(String oSS_PATH) { OSS_PATH = oSS_PATH; } public String getDOP_URL() { return DOP_URL; } public void setDOP_URL(String dOP_URL) { DOP_URL = dOP_URL; }}
4、调用方法
ConfigProperty.getInstance().getOSS_PATH
spring的@value注解使用
在实际开发中,很多时候也需要对普通变量进行初始化赋值,那么我们可以通过spring的@Value注解来解决
1、新建配置文件
2、加载配置文件
<!-- 加载配置文件 ,多个用逗号隔开--> <context:property-placeholder location="classpath:properties/antx_admin.properties" />
3、在实际代码中使用
@Value("${demo}")private String demo;
controller层加事务控制(@Transactional)
基本上spring的事务是配置在service层的,而事务生效也是在spring核心容器中,这是事务一致性保证的,如果我们有需求在controller层配置事务,来控制回滚等,那么就需要以下配置:
1、加入约束(有部分多余的约束,自行处理)
<!-- Bean头部 --><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
2、开始事务注解
<!-- controller层事务注解 --> <tx:annotation-driven/>
spring之BeanWrapperImpl实用举例
BeanWrapperImpl类是对BeanWrapper接口的默认实现,它包装了一个bean对象,缓存了bean的内省结果,并可以访问bean的属性、设置bean的属性值。BeanWrapperImpl类提供了许多默认属性编辑器,支持多种不同类型的类型转换,可以将数组、集合类型的属性转换成指定特殊类型的数组或集合。用户也可以注册自定义的属性编辑器在BeanWrapperImpl中。我们在实际工作中,可以有很多业务场景用到此类才实现通用方法,见下:
1、 需要将一个集合中所有对象某个具体字段的值全部取出来,以便后续使用,正常做法是循环取(如果后面别的集合也有此情况,又得循环),而通过BeanWrapperImpl,我们可以做一个通用的工具类。
第一个为去重的方法
public static <T> Set<T> getPropertieSet(Collection<?> collection, String propertyName, Class<T> clazz) { Set<T> set = new HashSet<T>(); if (null != collection) { for (Object item : collection) { BeanWrapper beanWrapper = new BeanWrapperImpl(item); @SuppressWarnings("unchecked") T property = (T) beanWrapper.getPropertyValue(propertyName); set.add(property); } } return set; } public static <T> List<T> getProperties(Collection<?> collection, String propertyName, Class<T> clazz) { List<T> list = new ArrayList<T>(); if (null != collection) { for (Object item : collection) { BeanWrapper beanWrapper = new BeanWrapperImpl(item); @SuppressWarnings("unchecked") T property = (T) beanWrapper.getPropertyValue(propertyName); list.add(property); } } return list; }
2、 需要根据集合中某个具体字段分组,取出此字段对应的具体对象来进行后续工作。
public static <T> List<T> getProperties(Collection<?> collection, String propertyName, Class<T> clazz) { List<T> list = new ArrayList<T>(); if (null != collection) { for (Object item : collection) { BeanWrapper beanWrapper = new BeanWrapperImpl(item); @SuppressWarnings("unchecked") T property = (T) beanWrapper.getPropertyValue(propertyName); list.add(property); } } return list; }
3、
/** * * @author: kuangkuang * @Description: 根据collection中T对象的某个属性keyPropertyName;和它对应的具体值,取出对应的该对象 * @Date: 2016年12月21日 上午11:10:48 * @param collection * @param keyPropertyName * @param valuePropertyName * @param allClazz * @return * @throws */ @SuppressWarnings("unchecked") public static <K, T> List<T> getBeanByProperty(Collection<T> collection, String keyPropertyName, K valuePropertyName, Class<K> allClazz) { List<T> result = new ArrayList<T>(); if (null != collection) { for (T item : collection) { BeanWrapper beanWrapper = new BeanWrapperImpl(item); K property = (K) beanWrapper.getPropertyValue(keyPropertyName); if (property .equals(valuePropertyName)) { result.add(item); } } } return result; }
4、
/** * 根据T中某个字段的值来获取在sources里面存在,在targets里面不存在的集合(支持当前传入字段的属性值为基础类型) * * @param sources * @param targets * @param argumentName(字段名称) * @return */ public static <T> List<T> diffCollection(List<T> sources, List<T> targets, String argumentName) { List<T> result = new ArrayList<T>(); if (CollectionUtils.isEmpty(targets)) { return result; } if (CollectionUtils.isEmpty(sources)) { return result; } Map<Object, T> map = initMap(sources, argumentName); for (T t : targets) { BeanWrapper beanWrapper = new BeanWrapperImpl(t); Object value = beanWrapper.getPropertyValue(argumentName); if (map.get(value) == null) { result.add(t); } } return result; } private static <T> Map<Object, T> initMap(List<T> sources, String argumentName) { Map<Object, T> resultMap = new HashMap<Object, T>(); for (T t : sources) { BeanWrapper beanWrapper = new BeanWrapperImpl(t); if (beanWrapper.getPropertyValue(argumentName) == null) { throw new RuntimeException("当前属性值为null"); } resultMap.put(beanWrapper.getPropertyValue(argumentName), t); } return resultMap; }
spring之controller层aop编程
实际开发中可能需要对controller每个用户调了什么方法进行一个记录,方便查询,例子如下:
定义一个切点类,对controller进行拦截,在调用controller下面所有方法之前执行前置处理,将登陆用户,ip地址,调了什么方法等信息写入数据库,方便后续管理。
1、 springMvc配置文件开启AspectJ,开启cglib代理(注意加入aop约束信息)
<!-- 启动AspectJ支持 --> <aop:aspectj-autoproxy proxy-target-class="true"/>
2、新建切点类(注意在配置文件中配置扫描包)
@Aspect@Componentpublic class ControllerAspect { private static Logger logger = LoggerFactory.getLogger(ControllerAspect.class); @Autowired private TbAspectLogService tbAspectLogService; @Pointcut("execution(* com.xx.web.admin.controller..*.*(..))") public void controller() { } @Before(value = "controller()") public void daBefore(JoinPoint joinPoint) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getRequest(); HttpSession session = request.getSession(); // 读取session中的用户 ShiroUserDo user = (ShiroUserDo) session.getAttribute("user"); if (null == user) { return; } // 请求的IP String ip = request.getRemoteAddr(); try { // *========控制台输出=========*// System.out.println("=====前置通知开始====="); System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")); System.out.println("请求人:" + user.getUserName()); System.out.println("请求IP:" + ip); // *========数据库日志=========*// TbAspectLogDo tbAspectLogDo = new TbAspectLogDo(); tbAspectLogDo.setMethod( (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")); tbAspectLogDo.setType(AspectLogTypeEnum.CONTROLLER.getCode()); tbAspectLogDo.setRequestIp(ip); tbAspectLogDo.setExceptionCode(null); tbAspectLogDo.setExceptionDetail(null); tbAspectLogDo.setParams(null); tbAspectLogDo.setCreater(user.toString()); long currentTimeMillis = System.currentTimeMillis(); tbAspectLogDo.setCreateTime(currentTimeMillis); tbAspectLogDo.setModifyTime(currentTimeMillis); // 保存数据库 tbAspectLogService.insert(tbAspectLogDo); System.out.println("=====前置通知结束====="); } catch (Exception e) { // 记录本地异常日志 logger.error("==前置通知异常=="); logger.error("异常信息:{}", e.getMessage()); } }}
spring全局异常处理(实现HandlerExceptionResolver方式)
有些时候,我们在程序中可能会漏掉某些异常,导致用户直接看到了异常报错页面,这是非常不人性化的体现,对于这些漏网之鱼,spring提供了全局异常处理方案,如下:
1、实现spring的HandlerExceptionResolver(注意在配置文件中配置扫描包)
@Componentpublic class xxHandlerExceptionResolver implements HandlerExceptionResolver { private static Logger logger = LoggerFactory.getLogger(xxHandlerExceptionResolver.class); @Autowired private TbAspectLogService tbAspectLogService; @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // 把漏网的异常信息记入日志 logger.error("Catch Exception: ", ex); HttpSession session = request.getSession(); // 读取session中的用户 ShiroUserDo user = (ShiroUserDo) session.getAttribute("user"); if (null == user) { return new ModelAndView("login"); } // *========数据库日志=========*// // 请求的IP String ip = request.getRemoteAddr(); TbAspectLogDo tbAspectLogDo = new TbAspectLogDo(); tbAspectLogDo.setRequestIp(ip); tbAspectLogDo.setExceptionCode(ex.getClass().getName()); tbAspectLogDo.setExceptionDetail(ex.getMessage()); tbAspectLogDo.setCreater(user.toString()); long currentTimeMillis = System.currentTimeMillis(); tbAspectLogDo.setCreateTime(currentTimeMillis); tbAspectLogDo.setModifyTime(currentTimeMillis); // 保存数据库 tbAspectLogService.insert(tbAspectLogDo); /* 使用response返回 */ response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); // 设置状态码 response.setContentType(MediaType.APPLICATION_JSON_VALUE); // 设置ContentType response.setCharacterEncoding("UTF-8"); // 避免乱码 response.setHeader("Cache-Control", "no-cache, must-revalidate"); try { response.getWriter().write("{\"success\":false,\"msg\":\"" + ex.getMessage() + "\"}"); } catch (IOException e) { logger.error("与客户端通讯异常:" + e.getMessage(), e); } return new ModelAndView(); }}
自定义注解接收json方式的参数
Spring自带的接收参数的方式有很多,但对于实际开发中可以有一些特殊需求,spring对于这种需求提供了支持,今天以接收json方法的参数为举例,见下:
1、
/** * 用来标识一个参数,使之以JSON方式来绑定数据(同一方法上只能出现一个该注解)。 * * @author kuangkuang */@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.PARAMETER })@Documentedpublic @interface JsonParam { public String value() default "";}
2、实现spring的HandlerMethodArgumentResolver参数解析器接口
import java.io.IOException;import java.lang.reflect.Array;import java.lang.reflect.ParameterizedType;import java.util.ArrayList;import java.util.Collection;import java.util.List;import javax.servlet.http.HttpServletRequest;import org.apache.commons.io.IOUtils;import org.springframework.core.MethodParameter;import org.springframework.web.bind.support.WebDataBinderFactory;import org.springframework.web.context.request.NativeWebRequest;import org.springframework.web.method.support.HandlerMethodArgumentResolver;import org.springframework.web.method.support.ModelAndViewContainer;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONException;import com.alibaba.fastjson.JSONObject;import com.alibaba.fastjson.util.TypeUtils;/** * * @ClassName: JsonParameterBinder * @Description: TODO * @author Comsys-kuangkuang * @date 2016年11月29日 上午11:53:45 * */public class JsonParameterBinder implements HandlerMethodArgumentResolver { private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY"; @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(JsonParam.class); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { Class<?> parameterType = parameter.getParameterType(); String name = parameter.getParameterName(); if (parameterType.getName().equals(Object.class.getName())) { throw new RuntimeException(String.format("no exact type assigned for parameter '%s'", name)); } String body = getRequestBody(webRequest); if (body != null) { Object obj = null; try { obj = JSON.parse(body); } catch (Exception e) { return null; } return parseResult(parameter, obj); } return null; } /** * * @author: kuangkuang * @Description: 获取json串 * @Date: 2016年11月28日 上午10:39:56 * @param webRequest * @return * @throws */ private String getRequestBody(NativeWebRequest webRequest) { HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); String jsonBody = (String) webRequest.getAttribute(JSONBODYATTRIBUTE, NativeWebRequest.SCOPE_REQUEST); if (jsonBody == null) { try { jsonBody = IOUtils.toString(servletRequest.getInputStream()); webRequest.setAttribute(JSONBODYATTRIBUTE, jsonBody, NativeWebRequest.SCOPE_REQUEST); } catch (IOException e) { throw new RuntimeException(e); } } return jsonBody; } /** * * @author: kuangkuang * @Description: 将JSON对象转换成指定的用户返回值类型 * @Date: 2016年11月28日 上午10:40:22 * @param parameter * @param resultObject * @return * @throws JSONException * @throws */ @SuppressWarnings({ "rawtypes", "unchecked" }) private Object parseResult(MethodParameter parameter, Object resultObject) throws JSONException { if (resultObject == null) { throw new JSONException("result is empty."); } Object result = null; Class<?> parameterType = parameter.getParameterType(); boolean isArray = parameterType.isArray(); boolean isCollection = Collection.class.isAssignableFrom(parameterType); Class<?> componentType = parameterType.getComponentType(); if ((isArray || isCollection) && resultObject instanceof JSONArray) { if (!isArray) { componentType = (Class<?>) (((ParameterizedType) parameter .getGenericParameterType()).getActualTypeArguments()[0]); } JSONArray jsonArray = (JSONArray) resultObject; int size = jsonArray.size(); if (isArray) { result = Array.newInstance(componentType, size); } else { result = new ArrayList(size); } for (int i = 0; i < size; i++) { Object value = jsonArray.getObject(i, componentType); if (isArray) { Array.set(result, i, value); } else { ((List) result).add(value); } } } else { if (resultObject instanceof JSONObject) { result = JSONObject.toJavaObject((JSONObject) resultObject, parameterType); } else { result = TypeUtils.castToJavaBean(resultObject, parameterType); } } return result; }}
- spring实用知识分享
- 【知识分享】实用链接收藏
- 实用网站/实用知识
- 分享知识!
- 知识分享。。。
- 知识分享
- 知识分享
- 分享知识,分享快乐
- 实用网址分享
- 分享实用副食制作
- Notepad++实用插件分享
- 简单实用的分享
- 实用小工具分享
- 实用资源推荐分享
- Command命令实用分享
- 实用电脑小知识
- weblogic相关实用知识
- java实用知识集
- Android-App性能优化之一
- ps☞抠图
- Python 学习基本语法
- 【学习总结】java高级特性之四种JAVA内部类总结
- STM32学习14
- spring实用知识分享
- Effective Objective-C 2.0 学习记录(一)
- 三、Android 网络评分机制
- 获取滚动条宽度
- 2016-12-20
- Quartz log异常
- 在本机的调试环境中安装一下docker,其它服务不需在本机安装
- centos7安装tomcat
- Git之同一台电脑连接多个远程仓库