Spring中使用自定义的注解校验器的实现
2016-10-25 17:58
603 查看
首先先学习一下注解,注解为我们在代码中添加信息提供了一种形式化的方法,使得我们在稍后的某个时刻可以方便地使用这些数据。
在日常的编码中我们一直都在使用注解,只是没有特别关注过,Java中内置了三种注解:@Override,@SuppressWarnings @Deprecated。相信只要学习过Java的同学一定是见过这些主角的 。
如果我们要写一个自定义的注解应该怎么呢?
首先需要定义一个注解标注出是自定义的注解
Java代码
/**
*
* @author zhangwei_david
* @version $Id: CustomerRule.java, v 0.1 2015年5月29日 下午10:12:16 zhangwei_david Exp $
*/
@Documented
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomerValidator {
}
这个注解中没有任何内容,属于标记注解
自定义 日期类型校验器的注解
Java代码
/**
*
* @author zhangwei_david
* @version $Id: Date.java, v 0.1 2015年5月29日 下午10:00:20 zhangwei_david Exp $
*/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@CustomerValidator
public @interface DateString {
String pattern() default "yyyy-MM-dd HH:mm:ss";
String errorCode() default "must date";
String message() default "must be date pattern";
}
, @Target是用来定义该注解将可以应用在什么地方,FIELD表示该注解应用在一个属性上,@Rectetion 用来定义该注解在哪一个级别可以使用 RUNTIME表示运行时。
String pattern() default "yyyy-MM-dd HH:mm:ss" 表示如果不指定pattern这个值的时候将返回默认值“yyyy-MM-dd HH:mm:ss” 。
有了自己的注解,那么就需要一个注解的处理器,定义一个处理器接
Java代码
/**
*自定义注解处理器接口
*
* @author zhangwei_david
* @version $Id: CustomerValidatorRule.java, v 0.1 2015年5月30日 上午8:51:52 zhangwei_david Exp $
*/
public interface CustomerValidatorRule {
/**
* 判断是否支持该注解
*
* @param annotation
* @param property
* @return
*/
public boolean support(Annotation annotation);
/**
* 校验处理
*
*
* @param annotation
* @param field
* @param errors
*/
public void valid(Annotation annotation, Object object, Field field, Errors errors)
throws Exception;
}
Java代码
/**
*
* @author zhangwei_david
* @version $Id: AbastractCustomerValidatorRule.java, v 0.1 2015年5月30日 上午11:22:19 zhangwei_david Exp $
*/
public abstract class AbastractCustomerValidatorRule implements CustomerValidatorRule {
/**
* @see com.cathy.core.service.annotation.rule.CustomerValidatorRule#support(java.lang.annotation.Annotation)
*/
public abstract boolean support(Annotation annotation);
/**
* @param <T>
* @see com.cathy.core.service.annotation.rule.CustomerValidatorRule#valid(java.lang.annotation.Annotation, java.lang.reflect.Field, org.springframework.validation.Errors)
*/
public void valid(Annotation annotation, Object target, final Field field, final Errors errors)
throws Exception {
preHandle(annotation, target, field, errors);
PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(target.getClass(),
field.getName());
Method reader = propertyDescriptor.getReadMethod();
Object property = reader.invoke(target);
validProperty(annotation, property, new PostHandler() {
public void postHanle(String errorCode, String message) {
errors.rejectValue(field.getName(), errorCode, message);
}
});
}
public static interface PostHandler {
public void postHanle(String errorCode, String message);
}
/**
*
*/
private void preHandle(Annotation annotation, Object target, Field field, Errors errors) {
Assert.notNull(target);
Assert.notNull(annotation);
Assert.notNull(errors);
Assert.notNull(field);
}
public abstract void validProperty(Annotation annotation, Object property,
PostHandler postHandler);
}
Java代码
/**
*
* @author zhangwei_david
* @version $Id: DateValidatorRule.java, v 0.1 2015年5月30日 上午11:17:09 zhangwei_david Exp $
*/
@CustomerRule
public class DateValidatorRule extends AbastractCustomerValidatorRule {
/**
* @see com.cathy.core.service.annotation.rule.CustomerValidatorRule#support(java.lang.annotation.Annotation, java.lang.Object)
*/
@Override
public boolean support(Annotation annotation) {
return annotation instanceof DateString;
}
/**
* @see com.cathy.core.service.annotation.rule.AbastractCustomerValidatorRule#validProperty(java.lang.annotation.Annotation, java.lang.Object)
*/
@Override
public void validProperty(Annotation annotation, Object property, PostHandler postHandler) {
DateString ds = (DateString) annotation;
if (parse(ds.pattern(), (String) property) == null) {
postHandler.postHanle(ds.errorCode(), ds.message());
}
}
private Date parse(String pattern, String property) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.parse(property);
} catch (ParseException e) {
//do noting
}
return null;
}
}
这样我们就有了一个注解处理器,为了方便扩展,该处使用注解的方式加载定义的注解处理器,这就需要定义一个标注是自定义的注解处理器的注解。
Java代码
/**
*
* @author zhangwei_david
* @version $Id: CustomerValidatorRule.java, v 0.1 2015年5月30日 下午12:51:20 zhangwei_david Exp $
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface CustomerRule {
}
Java代码
/**
*
* @author zhangwei_david
* @version $Id: CustomerValidatorProcesser.java, v 0.1 2015年5月30日 下午12:38:33 zhangwei_david Exp $
*/
public class CustomerValidatorConfig implements ApplicationContextAware {
private Map<Annotation, CustomerValidatorRule> rules = new ConcurrentHashMap<Annotation, CustomerValidatorRule>();
Map<String, Object> customerValidationRules = null;
/**
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
customerValidationRules = applicationContext
.getBeansWithAnnotation(CustomerRule.class);
System.out.println(customerValidationRules);
}
private CustomerValidatorRule findFormMap(Annotation annotation) {
for (Entry<String, Object> entry : customerValidationRules.entrySet()) {
if (entry.getValue() != null
&& ((CustomerValidatorRule) entry.getValue()).support(annotation)) {
return (CustomerValidatorRule) entry.getValue();
}
}
return null;
}
public CustomerValidatorRule findRule(Annotation annotation) {
CustomerValidatorRule customerValidatorRule = null;
if (!rules.containsKey(annotation)) {
CustomerValidatorRule cvr = findFormMap(annotation);
if (cvr != null) {
rules.put(annotation, cvr);
}
customerValidatorRule = cvr;
}
customerValidatorRule = rules.get(annotation);
return customerValidatorRule;
}
}
通过实现ApplicationContextAware接口,从上下文中自动加载处理器。
Java代码
/**
*
* @author zhangwei_david
* @version $Id: CustomerValidatorFactory.java, v 0.1 2015年5月30日 下午1:03:56 zhangwei_david Exp $
*/
@Component
public class CustomerValidatorFactory implements Validator {
@Autowired
private CustomerValidatorConfig customerValidatorConfig;
/**
* @see org.springframework.validation.Validator#supports(java.lang.Class)
*/
public boolean supports(Class<?> clazz) {
return true;
}
/**
* @see org.springframework.validation.Validator#validate(java.lang.Object, org.springframework.validation.Errors)
*/
public void validate(Object target, Errors errors) {
Assert.notNull(target);
Assert.notNull(errors);
List<Field> fileds = getFields(target.getClass());
for (Field field : fileds) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().getAnnotation(CustomerValidator.class) != null) {
try {
CustomerValidatorRule customerValidatorRule = customerValidatorConfig
.findRule(annotation);
if (customerValidatorRule != null) {
customerValidatorRule.valid(annotation, target, field, errors);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 获取class的fields。
*
* @param clazz bean所在的class
* @return
*/
private List<Field> getFields(Class<? extends Object> clazz) {
// 声明Field数组
List<Field> fields = new ArrayList<Field>();
// 如果class类型不为空
while (clazz != null) {
// 添加属性到属性数组
Collections.addAll(fields, clazz.getDeclaredFields());
clazz = clazz.getSuperclass();
}
return fields;
}
}
使用自定义校验处理器:
Java代码
/**
*
* @author zhangwei_david
* @version $Id: MyTest.java, v 0.1 2014年12月31日 下午9:25:49 zhangwei_david Exp $
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring.xml")
public class DemoTest {
@Autowired
private Validator customerValidatorFactory;
@Test
public void helloTest() {
Form form = new Form();
form.setCurrent("2015 11 11");
BindException errors = new BindException(form, "target");
customerValidatorFactory.validate(form, errors);
System.out.println(errors.getFieldErrors());
}
}
Java代码
/**
*
* @author zhangwei_david
* @version $Id: Form.java, v 0.1 2015年5月30日 下午4:04:06 zhangwei_david Exp $
*/
public class Form {
@DateString
private String current;
/**
* Getter method for property <tt>current</tt>.
*
* @return property value of current
*/
public String getCurrent() {
return current;
}
/**
* Setter method for property <tt>current</tt>.
*
* @param current value to be assigned to property current
*/
public void setCurrent(String current) {
this.current = current;
}
}
运行的结果是:
Java代码
五月 30, 2015 8:21:35 下午 org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
信息: @TestExecutionListeners is not present for class [class com.cathy.core.service.annotation.HelloServiceTest]: using defaults.
五月 30, 2015 8:21:36 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring.xml]
五月 30, 2015 8:21:36 下午 org.springframework.context.support.GenericApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@f7aae2: startup date [Sat May 30 20:21:36 CST 2015]; root of context hierarchy
五月 30, 2015 8:21:36 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@19627bc: defining beans [customerValidatorFactory,dateValidatorRule,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,customerValidatorConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
{dateValidatorRule=com.cathy.core.service.annotation.rule.DateValidatorRule@1758f2a}
[Field error in object 'target' on field 'current': rejected value [2015 11 11]; codes [must date.target.current,must date.current,must date.java.lang.String,must date]; arguments []; default message [must be date pattern]]
PS: spring的配置文件
Java代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
">
<context:component-scan base-package="com.cathy.core.service"/>
<bean id="customerValidatorConfig" class="com.cathy.core.service.annotation.handle.CustomerValidatorConfig"/>
</beans>
在日常的编码中我们一直都在使用注解,只是没有特别关注过,Java中内置了三种注解:@Override,@SuppressWarnings @Deprecated。相信只要学习过Java的同学一定是见过这些主角的 。
如果我们要写一个自定义的注解应该怎么呢?
首先需要定义一个注解标注出是自定义的注解
Java代码
/**
*
* @author zhangwei_david
* @version $Id: CustomerRule.java, v 0.1 2015年5月29日 下午10:12:16 zhangwei_david Exp $
*/
@Documented
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomerValidator {
}
这个注解中没有任何内容,属于标记注解
自定义 日期类型校验器的注解
Java代码
/**
*
* @author zhangwei_david
* @version $Id: Date.java, v 0.1 2015年5月29日 下午10:00:20 zhangwei_david Exp $
*/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@CustomerValidator
public @interface DateString {
String pattern() default "yyyy-MM-dd HH:mm:ss";
String errorCode() default "must date";
String message() default "must be date pattern";
}
, @Target是用来定义该注解将可以应用在什么地方,FIELD表示该注解应用在一个属性上,@Rectetion 用来定义该注解在哪一个级别可以使用 RUNTIME表示运行时。
String pattern() default "yyyy-MM-dd HH:mm:ss" 表示如果不指定pattern这个值的时候将返回默认值“yyyy-MM-dd HH:mm:ss” 。
有了自己的注解,那么就需要一个注解的处理器,定义一个处理器接
Java代码
/**
*自定义注解处理器接口
*
* @author zhangwei_david
* @version $Id: CustomerValidatorRule.java, v 0.1 2015年5月30日 上午8:51:52 zhangwei_david Exp $
*/
public interface CustomerValidatorRule {
/**
* 判断是否支持该注解
*
* @param annotation
* @param property
* @return
*/
public boolean support(Annotation annotation);
/**
* 校验处理
*
*
* @param annotation
* @param field
* @param errors
*/
public void valid(Annotation annotation, Object object, Field field, Errors errors)
throws Exception;
}
Java代码
/**
*
* @author zhangwei_david
* @version $Id: AbastractCustomerValidatorRule.java, v 0.1 2015年5月30日 上午11:22:19 zhangwei_david Exp $
*/
public abstract class AbastractCustomerValidatorRule implements CustomerValidatorRule {
/**
* @see com.cathy.core.service.annotation.rule.CustomerValidatorRule#support(java.lang.annotation.Annotation)
*/
public abstract boolean support(Annotation annotation);
/**
* @param <T>
* @see com.cathy.core.service.annotation.rule.CustomerValidatorRule#valid(java.lang.annotation.Annotation, java.lang.reflect.Field, org.springframework.validation.Errors)
*/
public void valid(Annotation annotation, Object target, final Field field, final Errors errors)
throws Exception {
preHandle(annotation, target, field, errors);
PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(target.getClass(),
field.getName());
Method reader = propertyDescriptor.getReadMethod();
Object property = reader.invoke(target);
validProperty(annotation, property, new PostHandler() {
public void postHanle(String errorCode, String message) {
errors.rejectValue(field.getName(), errorCode, message);
}
});
}
public static interface PostHandler {
public void postHanle(String errorCode, String message);
}
/**
*
*/
private void preHandle(Annotation annotation, Object target, Field field, Errors errors) {
Assert.notNull(target);
Assert.notNull(annotation);
Assert.notNull(errors);
Assert.notNull(field);
}
public abstract void validProperty(Annotation annotation, Object property,
PostHandler postHandler);
}
Java代码
/**
*
* @author zhangwei_david
* @version $Id: DateValidatorRule.java, v 0.1 2015年5月30日 上午11:17:09 zhangwei_david Exp $
*/
@CustomerRule
public class DateValidatorRule extends AbastractCustomerValidatorRule {
/**
* @see com.cathy.core.service.annotation.rule.CustomerValidatorRule#support(java.lang.annotation.Annotation, java.lang.Object)
*/
@Override
public boolean support(Annotation annotation) {
return annotation instanceof DateString;
}
/**
* @see com.cathy.core.service.annotation.rule.AbastractCustomerValidatorRule#validProperty(java.lang.annotation.Annotation, java.lang.Object)
*/
@Override
public void validProperty(Annotation annotation, Object property, PostHandler postHandler) {
DateString ds = (DateString) annotation;
if (parse(ds.pattern(), (String) property) == null) {
postHandler.postHanle(ds.errorCode(), ds.message());
}
}
private Date parse(String pattern, String property) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.parse(property);
} catch (ParseException e) {
//do noting
}
return null;
}
}
这样我们就有了一个注解处理器,为了方便扩展,该处使用注解的方式加载定义的注解处理器,这就需要定义一个标注是自定义的注解处理器的注解。
Java代码
/**
*
* @author zhangwei_david
* @version $Id: CustomerValidatorRule.java, v 0.1 2015年5月30日 下午12:51:20 zhangwei_david Exp $
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface CustomerRule {
}
Java代码
/**
*
* @author zhangwei_david
* @version $Id: CustomerValidatorProcesser.java, v 0.1 2015年5月30日 下午12:38:33 zhangwei_david Exp $
*/
public class CustomerValidatorConfig implements ApplicationContextAware {
private Map<Annotation, CustomerValidatorRule> rules = new ConcurrentHashMap<Annotation, CustomerValidatorRule>();
Map<String, Object> customerValidationRules = null;
/**
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
customerValidationRules = applicationContext
.getBeansWithAnnotation(CustomerRule.class);
System.out.println(customerValidationRules);
}
private CustomerValidatorRule findFormMap(Annotation annotation) {
for (Entry<String, Object> entry : customerValidationRules.entrySet()) {
if (entry.getValue() != null
&& ((CustomerValidatorRule) entry.getValue()).support(annotation)) {
return (CustomerValidatorRule) entry.getValue();
}
}
return null;
}
public CustomerValidatorRule findRule(Annotation annotation) {
CustomerValidatorRule customerValidatorRule = null;
if (!rules.containsKey(annotation)) {
CustomerValidatorRule cvr = findFormMap(annotation);
if (cvr != null) {
rules.put(annotation, cvr);
}
customerValidatorRule = cvr;
}
customerValidatorRule = rules.get(annotation);
return customerValidatorRule;
}
}
通过实现ApplicationContextAware接口,从上下文中自动加载处理器。
Java代码
/**
*
* @author zhangwei_david
* @version $Id: CustomerValidatorFactory.java, v 0.1 2015年5月30日 下午1:03:56 zhangwei_david Exp $
*/
@Component
public class CustomerValidatorFactory implements Validator {
@Autowired
private CustomerValidatorConfig customerValidatorConfig;
/**
* @see org.springframework.validation.Validator#supports(java.lang.Class)
*/
public boolean supports(Class<?> clazz) {
return true;
}
/**
* @see org.springframework.validation.Validator#validate(java.lang.Object, org.springframework.validation.Errors)
*/
public void validate(Object target, Errors errors) {
Assert.notNull(target);
Assert.notNull(errors);
List<Field> fileds = getFields(target.getClass());
for (Field field : fileds) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().getAnnotation(CustomerValidator.class) != null) {
try {
CustomerValidatorRule customerValidatorRule = customerValidatorConfig
.findRule(annotation);
if (customerValidatorRule != null) {
customerValidatorRule.valid(annotation, target, field, errors);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 获取class的fields。
*
* @param clazz bean所在的class
* @return
*/
private List<Field> getFields(Class<? extends Object> clazz) {
// 声明Field数组
List<Field> fields = new ArrayList<Field>();
// 如果class类型不为空
while (clazz != null) {
// 添加属性到属性数组
Collections.addAll(fields, clazz.getDeclaredFields());
clazz = clazz.getSuperclass();
}
return fields;
}
}
使用自定义校验处理器:
Java代码
/**
*
* @author zhangwei_david
* @version $Id: MyTest.java, v 0.1 2014年12月31日 下午9:25:49 zhangwei_david Exp $
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring.xml")
public class DemoTest {
@Autowired
private Validator customerValidatorFactory;
@Test
public void helloTest() {
Form form = new Form();
form.setCurrent("2015 11 11");
BindException errors = new BindException(form, "target");
customerValidatorFactory.validate(form, errors);
System.out.println(errors.getFieldErrors());
}
}
Java代码
/**
*
* @author zhangwei_david
* @version $Id: Form.java, v 0.1 2015年5月30日 下午4:04:06 zhangwei_david Exp $
*/
public class Form {
@DateString
private String current;
/**
* Getter method for property <tt>current</tt>.
*
* @return property value of current
*/
public String getCurrent() {
return current;
}
/**
* Setter method for property <tt>current</tt>.
*
* @param current value to be assigned to property current
*/
public void setCurrent(String current) {
this.current = current;
}
}
运行的结果是:
Java代码
五月 30, 2015 8:21:35 下午 org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
信息: @TestExecutionListeners is not present for class [class com.cathy.core.service.annotation.HelloServiceTest]: using defaults.
五月 30, 2015 8:21:36 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring.xml]
五月 30, 2015 8:21:36 下午 org.springframework.context.support.GenericApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@f7aae2: startup date [Sat May 30 20:21:36 CST 2015]; root of context hierarchy
五月 30, 2015 8:21:36 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@19627bc: defining beans [customerValidatorFactory,dateValidatorRule,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,customerValidatorConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
{dateValidatorRule=com.cathy.core.service.annotation.rule.DateValidatorRule@1758f2a}
[Field error in object 'target' on field 'current': rejected value [2015 11 11]; codes [must date.target.current,must date.current,must date.java.lang.String,must date]; arguments []; default message [must be date pattern]]
PS: spring的配置文件
Java代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
">
<context:component-scan base-package="com.cathy.core.service"/>
<bean id="customerValidatorConfig" class="com.cathy.core.service.annotation.handle.CustomerValidatorConfig"/>
</beans>
相关文章推荐
- 使用Spring自定义注解实现任务路由
- 使用Spring自定义注解实现任务路由的方法
- SpringBoot使用自定义注解+拦截器 实现日志记录
- 使用Spring自定义注解实现任务路由
- 使用自定义注解+Spring AOP 实现日志记录
- 使用SpringBoot通过自定义注解+AOP+全局异常处理实现参数统一非空校验
- 使用Spring AOP结合自定义Java注解实现动态数据源设置
- 使用Spring自定义注解实现任务路由
- J2EE项目使用自定义注解实现基于SpringMVC + Mybatis + Mysql的读写分离
- SpringBoot使用自定义注解实现权限拦截的示例
- spring3中使用注解方式实现定时器调度任务
- 使用注解,实现ssh项目中spring配置文件的零配置,约定优于配置
- (9) 使用Spring的注解方式实现AOP入门 以及 细节
- Spring使用注解的方式实现AOP
- 通过Spring实现对自定义注解属性进行资源注入
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- spring学习笔记7--使用spring进行面向切面的(AOP)编程(1)注解方式实现
- flex4 + spring + blazeds , 使用anonation(注解)机制,利用push技术的实现例子和过程。
- 使用Spring的注解方式实现AOP