java元注解+拦截器实现自定义注解
@CmwAutoWired:自定义依赖注入 注意:注入的接口和实现类需要在同一包名下,注解的是类则无限制
@FieldAnnotation:自定义属性注解
@MethodAnnotation:自定义方法注解
@MethodParam:自定义方法参数注解
1.web MVC配置
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
String os = System.getProperty("os.name");
registry.addResourceHandler("/templates/**.js").addResourceLocations("classpath:/templates/");
registry.addResourceHandler("/templates/**.css").addResourceLocations("classpath:/templates/");
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
}
@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new InterfaceInterceptor()).addPathPatterns("/feign/**","/testInt/**","/test/**")
.excludePathPatterns("/login","/","/user/login");
}
}
2.自定义注解 验证工具类
public class InterfaceUtil {
public static boolean method(HttpServletRequest request,Object obj) {
try {
Class clazz = obj.getClass();
Method[] declaredMethods = clazz.getDeclaredMethods();
List<Method> methodList = new ArrayList<>();
for (Method method : declaredMethods) {
if (method.isAnnotationPresent(MethodAnnotation.class)) {
checkMethodAnnotation(obj,method);
}
Parameter[] parameters = method.getParameters();
for(Parameter param : parameters){
if(param.isAnnotationPresent(MethodParam.class)){
checkMethodParam(request,param);
}
}
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
public static boolean field(Object obj) {
try {
Class clazz = obj.getClass();
Field[] declaredFields = clazz.getDeclaredFields();
List<Field> fields = new ArrayList<>();
for (Field field : declaredFields) {
field.setAccessible(true);
if (field.isAnnotationPresent(FieldAnnotation.class)) {
checkFieldAnnotation(obj,field);
}
if(field.isAnnotationPresent(CmwAutoWired.class) && field.get(obj)==null){
checkCmwAutoWired(obj, field);
}
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
private static void checkCmwAutoWired(Object obj,Field field) throws Exception{
CmwAutoWired annotation = field.getAnnotation(CmwAutoWired.class);
String name = field.getType().getName();
Class clazz = Class.forName(name);
if(clazz.isInterface()){
Class imClazz = null;
Package clazzPackage = clazz.getPackage();
String pk = clazzPackage.getName();
String path = pk.replace('.', '/');
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
URL url = classloader.getResource(path);
File file = new File(url.getPath());
File[] fileList = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if(pathname.getName().contains(".class")){
return true;
}
return false;
}
});
List<Class> classList = new ArrayList<>();
for(File f : fileList){
try {
String cUrl = f.getName().replace(".class","");
String className = clazz.getName().replace(clazz.getSimpleName(),cUrl);
Class aClass = Class.forName(className);
Class[] classes = aClass.getInterfaces();
for(Class c : classes){
if(c.getName().equals(clazz.getName())){
classList.add(aClass);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
if(classList!=null && classList.size()>0){
imClazz = classList.get(0);
}
if(imClazz==null){
throw new RuntimeException("注入失败,当前包下无接口的实现类");
}else{
if(field.get(obj)==null){
field.set(obj, imClazz.newInstance());
}
}
}else{
if(field.get(obj)==null){
field.set(obj, clazz.newInstance());
}
}
}
private static void checkFieldAnnotation(Object obj,Field field) throws Exception{
FieldAnnotation annotation = field.getAnnotation(FieldAnnotation.class);
if(field.get(obj)==null) {
field.set(obj, annotation.value());
}
if(annotation.isNotNull() && ("".equals(annotation.value()) || annotation.value()==null)){
throw new RuntimeException("field "+field.getName()+" Cannot be null");
}
if(annotation.value()!=null && !"".equals(annotation.value())){
if(annotation.value().length()>annotation.maxLength()){
throw new RuntimeException("field "+field.getName()+" length Cannot be longer than "+annotation.maxLength());
}
if(annotation.value().length()<annotation.minLength()){
throw new RuntimeException("field "+field.getName()+" length Cannot be less than "+annotation.minLength());
}
}
}
private static void checkMethodAnnotation(Object obj,Method method) throws Exception{
MethodAnnotation annotation = method.getAnnotation(MethodAnnotation.class);
Class getclazz = annotation.clazz();
String getmethod = annotation.method();
Class[] parameterTypes = annotation.parameterTypes();
Object getobj = getclazz.newInstance();
Method getclazzMethod = getclazz.getMethod(getmethod,parameterTypes);
Object result = getclazzMethod.invoke(getobj);
System.out.println("输出:"+result.toString());
}
private static void checkMethodParam(HttpServletRequest request,Parameter param) throws Exception{
MethodParam annotation = param.getAnnotation(MethodParam.class);
Object value = request.getParameter(param.getName());
if(value==null){
if(annotation.require()){
throw new RuntimeException("param " + param.getName() + " Cannot be null");
}
}else {
if (value instanceof String) {
String str = (value != null ? String.valueOf(value) : "");
if (annotation.require() && ("".equals(str) || str == null)) {
throw new RuntimeException("param " + param.getName() + " Cannot be null");
}
if (str.length() > annotation.maxLength()) {
throw new RuntimeException("param " + param.getName() + " length Cannot be longer than " + annotation.maxLength());
}
if (str.length() < annotation.minLength()) {
throw new RuntimeException("param " + param.getName() + " length Cannot be less than " + annotation.minLength());
}
}
}
}
}
3.自定义注解 拦截器
@Component
public class InterfaceInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("进入 Controller 某个方法之前");
HandlerMethod handlerMethod = ((HandlerMethod) handler);
Object obj = handlerMethod.getBean();
if (!InterfaceUtil.field(obj)) {
return false;
}
if (!InterfaceUtil.method(request, obj)) {
return false;
}
Method method = ((HandlerMethod) handler).getMethod();
System.out.println("类名:" + obj.getClass().getName());
System.out.println("方法名:" + method.getName());
try {
request.setAttribute("startTime", new Date().getTime());
if (true) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("TimeInterceptor 运行 Controller 某个方法时,方法抛出异常将不进入此方法");
long start = (long) request.getAttribute("startTime");
System.out.println("TimeInterceptor 处理时长为:" + (new Date().getTime() - start));
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception {
System.out.println("TimeInterceptor 完成 Controller 某个方法");
long start = (long) request.getAttribute("startTime");
System.out.println("TimeInterceptor 处理时长为:" + (new Date().getTime() - start));
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("TimeInterceptor 执行 afterConcurrentHandlingStarted");
}
}
4.注解声明
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CmwAutoWired {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotation {
String value() default "";
boolean isNotNull() default false;
int maxLength() default 100;
int minLength() default 0;
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnnotation {
String module() default "";
Class clazz();
String method() default "";
Class[] parameterTypes() default {};
}
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodParam {
boolean require() default true;
int maxLength() default 20;
int minLength() default 0;
}
5.测试
@RestController
@RequestMapping("/test")
public class FieldController implements LoginFace {
@FieldAnnotation(value = "123456aaa",isNotNull = true)
private String testInt;
@CmwAutoWired
public CmwDaoImpl cmwDao;
@Override
@RequestMapping("/testInt")
public String testInt(){
return "获取属性:" + testInt;
}
@RequestMapping("/getout")
public String getout(){
return "获取属性:" + cmwDao.getOut();
}
@RequestMapping("/tostring")
public String tostring(){
return "获取属性:" + cmwDao.toString();
}
}
@RestController
@RequestMapping("/test")
public class MainTestController {
@CmwAutoWired
private LoggerApply loggerApply;
@RequestMapping("/out")
@MethodAnnotation(clazz = CmwDaoImpl.class,method = "toString")
public String test(@MethodParam(require = true,maxLength = 5,minLength = 1) String module) throws Exception{
try {
loggerApply.lingLogger(module);
return "success";
}catch (Exception e){
return "faild";
}
}
}