最近很多小伙伴都在问java–Autowired在CustomConstraint验证器中给出Null值和java当中实现验证的是什么这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓
最近很多小伙伴都在问java – Autowired在Custom Constraint验证器中给出Null值和java当中实现验证的是什么这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展002-Struts2的action中@Autowired注入service为NULL、@Autowired注解在非Controller中注入为null、@Autowired配合@PostConstruct注入问题、@Compenent,@Autowired,@PostConstruct自实现等相关知识,下面开始了哦!
本文目录一览:- java – Autowired在Custom Constraint验证器中给出Null值(java当中实现验证的是什么)
- 002-Struts2的action中@Autowired注入service为NULL
- @Autowired注解在非Controller中注入为null
- @Autowired配合@PostConstruct注入问题
- @Compenent,@Autowired,@PostConstruct自实现
java – Autowired在Custom Constraint验证器中给出Null值(java当中实现验证的是什么)
我对Spring来说是全新的,我已经在SO上找到了一些问题的答案.以下是链接:
Spring 3.1 Autowiring does not work inside custom constraint validator
Autowiring a service into a validator
Autowired Repository is Null in Custom Constraint Validator
我有一个Spring项目,我想在其中使用Hibernate Validator进行对象验证.基于我在网上阅读的内容和一些论坛,我试图注入验证器如下:
@Bean
public Validator validator() {
return new LocalValidatorfactorybean().getValidator();
}
但无论我在哪里使用
@Autowired
Validator validator;
它采用了Spring的验证器实现而不是Hibernate的验证器.我无法弄清楚如何准确地注入Hibernate验证器并简单地将其自动装配到其他类中,所以我使用了一个便宜的技巧,现在我的Java Config看起来像这样
@Bean
public Validator validator() {
// ValidatorImpl is Hibernate's implementation of the Validator
return new ValidatorImpl();
}
(我真的很感激,如果有人能指出我如何避免以这种Hacky方式获得Hibernate Validator的正确方向)
但是让我们来看看主要问题:
这是自定义验证定义
@Target( { METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,ParaMETER } )
@Retention(RUNTIME)
@Constraint(validatedBy = EmployeeValidator.class)
@Documented
public @interface EmployeeValidation {
String message() default "{constraints.employeeConstraints}";
public abstract Class
我的自定义验证器
public class EmployeeValidator implements ConstraintValidator
在上面的Custom Constraint Validator中,我得到employeeService null.我知道Spring启动时没有实例化ConstraintValidator的任何实现,但我认为添加ValidatorImpl()实际上会解决这个问题.但事实并非如此.
现在我陷入了一个非常hacky的解决方法,我不想继续这样的代码.有人可以帮助我解决我的情况.
附:这些是我在Java Config文件中的导入:
import org.hibernate.validator.HibernateValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorfactorybean;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
最佳答案
我希望解决方案可以帮助某人:
@Bean
public Validator validator () {
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure().constraintValidatorFactory(new SpringConstraintValidatorFactory(autowireCapablebeanfactory))
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
使用SpringConstraintValidatorFactory初始化验证器以便注入工作并将验证器实现提供为Hibernate.class以下列方式工作:
>您的项目将由您选择的图书馆验证
>您的自定义验证器将能够使用Spring的功能,同时通过Hibernate执行验证.
这个怎么运作:
Hibernate的ConstraintValidtorFactory不会初始化任何ConstraintValidator,除非它们被调用但SpringConstraintValidatorFactory通过向它提供AutowireCapablebeanfactory来实现.
编辑
正如@shabyasaschi的一条评论中所提到的,要注入autowireCapablebeanfactory,您可以将方法签名更改为:
Validator validator(final AutowireCapablebeanfactory autowireCapablebeanfactory) {
或者在配置文件中为它添加getter和setter,如下所示:
public AutowireCapablebeanfactory getAutowireCapablebeanfactory() {
return autowireCapablebeanfactory;
}
public void setAutowireCapablebeanfactory(AutowireCapablebeanfactory autowireCapablebeanfactory) {
this.autowireCapablebeanfactory = autowireCapablebeanfactory;
}
002-Struts2的action中@Autowired注入service为NULL
错误代码:只是某个action中的service自动注入失败为NULL
解决方法:struts.xml文件中添加如下配置
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true" />
相关说明:
- struts.objectFactory
设置struts2的对象工厂,默认(struts),类名org.apache.struts2.impl.StrutsObjectFactory,当引入struts2-spring插件之后,则被修改为org.apache.struts2.spring.StrutsSpringObjectFactory
- struts.objectFactory.spring.autoWire
可选值(name, type, auto, constructor,name)(默认name),设置spring的自动装配方式,只有引入spring插件后才有效。
- struts.objectFactory.spring.autoWire.alwaysRespect
(默认false)设置是否总是以自动装配策略创建对象。
@Autowired注解在非Controller中注入为null
/**
* Created by huangzhenyang on 2017/11/2.
* Token 工具类
*/
@Component // 关键1,将该工具类注册为组件, 加粗!!!
public class TokenUtil {
@Autowired
private TokenRepository tokenRepository;
@Autowired
private TokenService tokenService;
public static TokenUtil tokenUtil; // 关键2
// 关键3
@PostConstruct
public void init() {
tokenUtil = this;
tokenUtil.tokenRepository = this.tokenRepository;
}
tokenUtil .tokenService......
原文链接:https://blog.csdn.net/qq_35056292/article/details/78430777
………………
更新
然后又找到另一个方法
使用@Autowired 注入 ApplicationContext applicationContext;
TokenService tokenService = (tokenService)applicationContext.getBean("tokenService");
然后通过tokenService 获取tokenService 中的接口
注:没有测试自己填坑 .0.0.
————————————————
2020-05-07 更新
又发现一种新写法,就是在类中添加@Component注解,把他注册为一个工具类,然后里面的方法不要写成静态方法,在需要用的地方用@Resource
注解注入一下,这样也可以避免在静态方法中使用注入的时候为null的情况
------------------------------------------------------------------------------------------------------------------------
@Autowired配合@PostConstruct注入问题
debug时@Autowired注入属性抛出异常,但是在@PostConstruct中却还能注入!这是什么原理?
@Compenent,@Autowired,@PostConstruct自实现
本来是想为安卓开发一套可以依赖注入的标签,但是发现安卓很难找到选定包内的java或者class文件。所以只能当做学习参考了,全套代码如下
package com.guanjian.annotion; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by Administrator on 2018-06-11. */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Autowired { }
package com.guanjian.annotion; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by Administrator on 2018-06-11. */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Component { }
package com.guanjian.annotion; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by Administrator on 2018-06-11. */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface PostConstruct { }
package com.guanjian.util; import com.guanjian.utils.StringUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * 类操作工具类 * Created by Administrator on 2018-06-11. */ public final class ClassUtil { private static final Logger LOGGER = LoggerFactory.getLogger(ClassUtil.class); /** * 获取类加载器 * @return */ public static ClassLoader getClassLoader() { return Thread.currentThread().getContextClassLoader(); } /** * 加载类 * @param className * @param isInitialized * @return */ public static Class<?> loadClass(String className,boolean isInitialized) { Class<?> cls; try { cls = Class.forName(className,isInitialized,getClassLoader()); } catch (ClassNotFoundException e) { LOGGER.error("load class failure",e); throw new RuntimeException(e); } return cls; } /** * 获取制定包名下的所有类 * @param packageName * @return */ public static Set<Class<?>> getClassSet(String packageName) { Set<Class<?>> classSet = new HashSet<Class<?>>(); try { Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".","/")); while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (url != null) { String protocol = url.getProtocol(); if (protocol.equals("file")) { String packagePath = url.getPath().replaceAll("%20"," "); addClass(classSet,packagePath,packageName); }else if (protocol.equals("jar")) { JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection(); if (jarURLConnection != null) { JarFile jarFile = jarURLConnection.getJarFile(); if (jarFile != null) { Enumeration<JarEntry> jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith(".class")) { String className = jarEntryName.substring(0,jarEntryName.lastIndexOf(".")).replaceAll("/","."); doAddClass(classSet,className); } } } } } } } } catch (Exception e) { LOGGER.error("get class set failure",e); throw new RuntimeException(e); } return classSet; } private static void addClass(Set<Class<?>> classSet, String packagePath, final String packageName) { File[] files = new File(packagePath).listFiles(new FileFilter() { public boolean accept(File pathname) { return (pathname.isFile() && pathname.getName().endsWith(".class")) || pathname.isDirectory(); } }); for (File file:files) { String fileName = file.getName(); if (file.isFile()) { String className = fileName.substring(0,fileName.lastIndexOf(".")); if (StringUtil.isNotEmpty(packagePath)) { className = packageName + "." + className; } doAddClass(classSet,className); }else { String subPackagePath = fileName; if (StringUtil.isNotEmpty(packagePath)) { subPackagePath = packagePath + "/" +subPackagePath; } String subPackageName = fileName; if (StringUtil.isNotEmpty(packageName)) { subPackageName = packageName + "." +subPackageName; } addClass(classSet,subPackagePath,subPackageName); } } } private static void doAddClass(Set<Class<?>> classSet,String className) { Class<?> cls = loadClass(className,false); classSet.add(cls); } }
package com.guanjian.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Field; /** * 反射工具类 * Created by Administrator on 2018-06-11. */ public final class ReflectionUtil { private static final Logger LOGGER = LoggerFactory.getLogger(ReflectionUtil.class); /** * 创建实例 * @param cls * @return */ public static Object newInstance(Class<?> cls) { Object instance; try { instance = cls.newInstance(); } catch (Exception e) { LOGGER.error("new instance failure",e); throw new RuntimeException(e); } return instance; } /** * 设置成员变量值 * @param obj * @param field * @param value */ public static void setField(Object obj, Field field,Object value) { try { field.setAccessible(true); field.set(obj,value); } catch (IllegalAccessException e) { LOGGER.error("set field failure",e); throw new RuntimeException(e); } } }
package com.guanjian.util; import com.guanjian.annotion.Component; import java.util.HashSet; import java.util.Set; /** * 类操作助手类 * Created by Administrator on 2018-06-11. */ public final class ClassHelper { /** * 定义类集合(用于存放所加载的类) * @param basePackage */ private static Set<Class<?>> CLASS_SET; /** * 扫描所有的包,获取类集合放入CLASS_SET * @param basePackage */ public static void setClassSet(String basePackage) { CLASS_SET = ClassUtil.getClassSet(basePackage); } /** * 获取应用包名下的所有类 * @return */ public static Set<Class<?>> getClassSet() { return CLASS_SET; } /** * 获取应用包名下所有Comonent类 * @return */ public static Set<Class<?>> getComponentClassSet() { Set<Class<?>> classSet = new HashSet<Class<?>>(); for (Class<?> cls:CLASS_SET) { if (cls.isAnnotationPresent(Component.class)) { classSet.add(cls); } } return classSet; } /** * 获取应用包名下所有Bean类 * @return */ public static Set<Class<?>> getBeanClassSet() { Set<Class<?>> beanClassSet = new HashSet<Class<?>>(); beanClassSet.addAll(getComponentClassSet()); return beanClassSet; } }
package com.guanjian.util; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Bean助手类 * Created by Administrator on 2018-06-11. */ public final class BeanHelper { /** * 定义Bean映射(用于存放Bean类与Bean实例的映射关系) */ private static final Map<Class<?>,Object> BEAN_MAP = new HashMap<Class<?>, Object>(); /** * 获取所有的映射关系 */ public static void setBeanMap() { Set<Class<?>> beanClassSet = ClassHelper.getBeanClassSet(); for (Class<?> beanClass:beanClassSet) { Object obj = ReflectionUtil.newInstance(beanClass); BEAN_MAP.put(beanClass,obj); } } /** * 获取Bean映射 * @return */ public static Map<Class<?>,Object> getBeanMap() { return BEAN_MAP; } /** * 获取Bean实例 * @param cls * @param <T> * @return */ public static <T> T getBean(Class<T> cls) { if (!BEAN_MAP.containsKey(cls)) { throw new RuntimeException("Can not get bean by class:" + cls); } return (T)BEAN_MAP.get(cls); } }
package com.guanjian.util; import com.guanjian.annotion.Autowired; import com.guanjian.annotion.PostConstruct; import com.guanjian.utils.ArrayUtil; import com.guanjian.utils.CollectionUtil; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Map; /** * Created by Administrator on 2018-06-11. */ public final class IocHelper { public static void ioc(){ //获取所有的Bean类与Bean实例之间的映射关系 Map<Class<?>,Object> beanMap = BeanHelper.getBeanMap(); if (CollectionUtil.isNotEmpty(beanMap)) { //遍历Bean Map for (Map.Entry<Class<?>,Object> beanEntry:beanMap.entrySet()) { //从BeanMap中获取Bean类与Bean实例 Class<?> beanClass = beanEntry.getKey(); Object beanInstance = beanEntry.getValue(); //获取Bean类定义的所有成员变量 Field[] beanFields = beanClass.getDeclaredFields(); if (ArrayUtil.isNotEmpty(beanFields)) { //遍历Bean Field for (Field beanField:beanFields) { //判断当前Bean Field是否带有Autowired注解 if (beanField.isAnnotationPresent(Autowired.class)) { //在Bean Map中获取Bean Field对应的实例 Class<?> beanFieldClass = beanField.getType(); Object beanFieldInstance = beanMap.get(beanFieldClass); if (beanFieldInstance != null) { //通过反射初始化BeanField的值 ReflectionUtil.setField(beanInstance,beanField,beanFieldInstance); } } } } Method[] beanMethods = beanClass.getMethods(); if (ArrayUtil.isNotEmpty(beanMethods)) { //遍历method for (Method method:beanMethods) { //判断当前注解是否有PostConstruct注解 if (method.isAnnotationPresent(PostConstruct.class)) { try { //执行该方法 method.invoke(beanInstance,null); } catch (Exception e) { e.printStackTrace(); } } } } } } } }
package com.guanjian.manage; import com.guanjian.util.BeanHelper; import com.guanjian.util.ClassHelper; import com.guanjian.util.IocHelper; /** * Created by Administrator on 2018-06-11. */ public class Manager { public static Object getBean(Class<?> beanClass) { return BeanHelper.getBean(beanClass); } public static void scanAndImp(String basePackage) { ClassHelper.setClassSet(basePackage); BeanHelper.setBeanMap(); IocHelper.ioc(); } }
测试代码
package com.guanjian.test.compent; import com.guanjian.annotion.Component; import com.guanjian.annotion.PostConstruct; /** * Created by Administrator on 2018-06-11. */ @Component public class Test1 { private String hello; @PostConstruct public void init() { hello = "你好"; } public void show() { System.out.println(hello); } }
package com.guanjian.test.compent; import com.guanjian.annotion.Autowired; import com.guanjian.annotion.Component; /** * Created by Administrator on 2018-06-11. */ @Component public class Test2 { @Autowired private Test1 test1; public void show() { test1.show(); } }
package com.guanjian.test; import com.guanjian.manage.Manager; import com.guanjian.test.compent.Test2; /** * Created by Administrator on 2018-06-11. */ public class Test { public static void main(String[] args) { Manager.scanAndImp("com.guanjian.test"); Test2 test2 = (Test2)Manager.getBean(Test2.class); test2.show(); } }
关于java – Autowired在Custom Constraint验证器中给出Null值和java当中实现验证的是什么的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于002-Struts2的action中@Autowired注入service为NULL、@Autowired注解在非Controller中注入为null、@Autowired配合@PostConstruct注入问题、@Compenent,@Autowired,@PostConstruct自实现等相关知识的信息别忘了在本站进行查找喔。
本文标签: