使用BeanPostProcessor接口对受管Bean进行预处理,通过自定义Annotation,获取所有Controller的Url
2013-01-30 16:25
851 查看
有时候,我们希望在Spring IoC容器初始化受管Bean之前、属性设置之后对该Bean先做一些预处理,或者在容器销毁受管Bean之前自己释放资源。那么该如何实现呢?Spring
IoC为我们提供了多种方法来实现受管Bean的预处理和后处理。
在Spring中定义了BeanPostProcessors接口。
项目实例:在项目中获取部分Controller的Url
1、自定义Annotation
2、在需要获取Url的Controller上加上自定义Annotation
3、解析Annotation里面的内容
4、定义了BeanPostProcessors进行预处理
@Configuration:与Spring配置文件(application-config.xml)配置bean类似
5、获取url数据
IoC为我们提供了多种方法来实现受管Bean的预处理和后处理。
在Spring中定义了BeanPostProcessors接口。
项目实例:在项目中获取部分Controller的Url
1、自定义Annotation
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @interface Function { String name() default ""; String description() default ""; }
2、在需要获取Url的Controller上加上自定义Annotation
@RequestMapping(method = RequestMethod.GET) @Function(name = "文件发送", description = "政企通-文件发送") public String send(HttpServletRequest request,ModelMap model) throws ServletRequestBindingException { User user = (User) Application.getCurrentUserInfo().getCurrentUser(); List<UserComGroup> userComGroups = userComGroupManager.query().filterEqual("user", user).list(); super.storeRequestParams(model); model.put("userComGroups", userComGroups); return view("send"); }
3、解析Annotation里面的内容
public class RouterInfo { private String beanName; private String beanClass; private String invokeMethod; private String requestMethod; private String url;
...
}
public class FunctionInfo extends RouterInfo{ //功能名称 private String name; //功能描述 private String description; ... }
public class FunctionInfoCollector implements BeanInfoCollector<FunctionInfo> { private List<FunctionInfo> functionInfos = Lists.newArrayList(); public void collect(Object bean, String beanName) { final Class<?> beanClazz = bean.getClass(); if (beanClazz.isAnnotationPresent(Controller.class)) { for(Method method : beanClazz.getMethods()) { if (method.isAnnotationPresent(Function.class) && method.isAnnotationPresent(RequestMapping.class)) { Function function = method.getAnnotation(Function.class); if (function != null) { Map<String, MethodInfo> urls = determineUrlsForHandler(bean, beanName); for (Map.Entry<String, MethodInfo> entry : urls.entrySet()) { MethodInfo methodInfo = entry.getValue(); if(methodInfo.invokeMethod.equals(method.getName())) { functionInfos.add(new FunctionInfo(function.name(), function.description(), beanName, beanClazz.getName(), methodInfo.invokeMethod, methodInfo.requestMethod, methodInfo.url)); } } } } } } } public List<FunctionInfo> getBeanInfos() { return Collections.unmodifiableList(functionInfos); } protected Map<String, MethodInfo> determineUrlsForHandler(Object bean, String beanName) { Class<?> handlerType = bean.getClass(); RequestMapping mapping = handlerType .getAnnotation(RequestMapping.class); if (mapping != null) { // @RequestMapping found at type level Map<String, MethodInfo> urls = new LinkedHashMap<String, MethodInfo>(); String[] typeLevelPatterns = mapping.value(); if (typeLevelPatterns.length > 0) { // @RequestMapping specifies paths at type level Map<String, MethodInfo> methodLevelPatterns = determineUrlsForHandlerMethods( handlerType, true); for (String typeLevelPattern : typeLevelPatterns) { if (!typeLevelPattern.startsWith("/")) { typeLevelPattern = "/" + typeLevelPattern; } for (Map.Entry<String, MethodInfo> entry : methodLevelPatterns .entrySet()) { final MethodInfo methodInfo = entry.getValue(); String methodLevelPattern = methodInfo.getUrl(); if (methodLevelPattern != null) { String combinedPattern = getPathMatcher().combine( typeLevelPattern, methodLevelPattern); addUrlsForPath(urls, methodInfo.getInvokeMethod(), methodInfo.getRequestMethod(), combinedPattern); } } } return urls; } else { // actual paths specified by @RequestMapping at method level return determineUrlsForHandlerMethods(handlerType, false); } } else if (AnnotationUtils .findAnnotation(handlerType, Controller.class) != null) { // @RequestMapping to be introspected at method level return determineUrlsForHandlerMethods(handlerType, false); } else { return null; } } private String getRequestMethod(RequestMapping mapping) { if (mapping.method().length == 0) { return "*"; } StringBuilder sb = new StringBuilder(); RequestMethod[] requestMethods = mapping.method(); for (int i = 0; i < requestMethods.length; i++) { if (i != 0) { sb.append(" | "); } sb.append(requestMethods[i]); } return sb.toString(); } private PathMatcher getPathMatcher() { return new AntPathMatcher(); } protected Map<String, MethodInfo> determineUrlsForHandlerMethods( Class<?> handlerType, final boolean hasTypeLevelMapping) { Map<String, MethodInfo> subclassResult = determineUrlsForHandlerMethods(handlerType); if (subclassResult != null) { return subclassResult; } final Map<String, MethodInfo> urls = new LinkedHashMap<String, MethodInfo>(); Class<?>[] handlerTypes = Proxy.isProxyClass(handlerType) ? handlerType .getInterfaces() : new Class<?>[] { handlerType }; for (Class<?> currentHandlerType : handlerTypes) { ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() { public void doWith(Method method) { RequestMapping mapping = AnnotationUtils .findAnnotation(method, RequestMapping.class); final String methodName = method.getName(); if (mapping != null) { String[] mappedPatterns = mapping.value(); if (mappedPatterns.length > 0) { for (String mappedPattern : mappedPatterns) { if (!hasTypeLevelMapping && !mappedPattern .startsWith("/")) { mappedPattern = "/" + mappedPattern; } addUrlsForPath(urls, methodName, getRequestMethod(mapping), mappedPattern); } } else if (hasTypeLevelMapping) { // empty method-level RequestMapping addUrlsForPath(urls, methodName, getRequestMethod(mapping), ""); } } } }, ReflectionUtils.NON_BRIDGED_METHODS); } return urls; } protected Map<String, MethodInfo> determineUrlsForHandlerMethods( Class<?> handlerType) { return null; } protected void addUrlsForPath(Map<String, MethodInfo> urls, String invokeMethod, String requestMethod, String path) { String url = path; } urls.put(invokeMethod, new MethodInfo(invokeMethod, requestMethod, url)); } private static class MethodInfo { private final String invokeMethod; private final String requestMethod; private final String url; public MethodInfo(String invokeMethod, String requestMethod, String url) { this.invokeMethod = invokeMethod; this.requestMethod = requestMethod; this.url = url; } public String getInvokeMethod() { return invokeMethod; } public String getRequestMethod() { return requestMethod; } public String getUrl() { return url; } } }
4、定义了BeanPostProcessors进行预处理
@Configuration:与Spring配置文件(application-config.xml)配置bean类似
@Configuration public class MainConfig { private AnnotationSessionFactoryBean annotationSessionFactoryBean; @Inject public void setAnnotationSessionFactoryBean( AnnotationSessionFactoryBean annotationSessionFactoryBean) { this.annotationSessionFactoryBean = annotationSessionFactoryBean; } @Bean(name = "systemInfoBeanPostProcessor") public BeanPostProcessor systemInfoBeanPostProcessor() { return new BeanInfoCollectorBeanPostProcessor().addBeanInfoCollector(functionInfoCollector()); } @Bean(name = "functionInfoCollector") public FunctionInfoCollector functionInfoCollector() { return new FunctionInfoCollector(); } public static class BeanInfoCollectorBeanPostProcessor implements BeanPostProcessor {//实现BeanPostProcessor接口 private static Logger logger = LoggerFactory .getLogger(BeanInfoCollectorBeanPostProcessor.class); private final List<BeanInfoCollector<?>> beanInfoCollectors = new ArrayList<BeanInfoCollector<?>>(); public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) { for (BeanInfoCollector<?> collector : beanInfoCollectors) { try { collector.collect(bean, beanName); } catch (Exception e) { logger.warn("BeanInfoCollector " + collector + "执行出错!", e); } } return bean; } public <T> void setBeanInfoCollectors( List<BeanInfoCollector<T>> beanInfoCollectors) { this.beanInfoCollectors.addAll(beanInfoCollectors); } public <T> BeanInfoCollectorBeanPostProcessor addBeanInfoCollector( BeanInfoCollector<T> beanInfoCollector) { beanInfoCollectors.add(beanInfoCollector); return this; } } }
5、获取url数据
@Inject private FunctionInfoCollector functionInfoCollector; public String index(ModelMap model) throws ServletRequestBindingException { List<FunctionInfo> functionInfos = functionInfoCollector.getBeanInfos();
}
相关文章推荐
- 使用BeanPostProcessor接口对受管Bean进行预处理
- 使用BeanPostProcessor接口对受管Bean进行预处理
- 使用BeanPostProcessor接口对受管Bean进行预处理
- 使用BeanPostProcessor接口对受管Bean进行预处理
- BeanPostProcessor 的使用,实现在对象初始化之前或者之后对对象进行操作
- windows phone 7 通过Post提交URL到服务器,从服务器获取数据(比如登陆时候使用)
- Spring BeanPostProcessor接口使用详解
- 使用自定义annotation接口进行aspectj动态缓存
- 使用XIB自定义一个UIView,然后将这个view添加到controller的view 上(相当于所有界面都通过xib来实现)
- BeanPostProcessor实现Environment获取到自定义properties解决过程
- windows phone 7 通过Post提交URL到服务器,从服务器获取数据(比如登陆时候使用)
- 通过ApplicationContextAware接口获取Spring配置文件中的所有Bean
- 【spring源码分析】BeanDefinitionRegistryPostProcessor接口可自定义bean加入IOC
- spring mvc 通过bean获取form的参数和并且进行服务器验证 ,而且支持多个文件上传的用法。html使用form_data
- 自定义表格控件(通过TabLayout+TabRow)获取表格所有数据,并对表格进行相关事件监听
- 通过BeanFactoryPostProcessor来获取bean
- Spring中使用两种Aware接口自定义获取bean
- Android 使用三种方式获取网页(通过Post,Get进行表单的提交)
- Android 使用三种方式获取网页(通过Post,Get进行表单的提交)
- 使用XIB自定义一个UIView,然后将这个view添加到controller的view 上(相当于所有界面都通过xib来实现)