项目使用的是SSM体系,spring的配置如下,配置没问题,因为我发现其他文件中的@Value可以使用,只有一处@Value失效了。
spring-servlet.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:aop="http://www.springframework.org/schema/aop" 7 xmlns:tx="http://www.springframework.org/schema/tx" 8 xmlns:websocket="http://www.springframework.org/schema/websocket" 9 xsi:schemaLocation="http://www.springframework.org/schema/beans 10 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 11 http://www.springframework.org/schema/mvc 12 http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 13 http://www.springframework.org/schema/context 14 http://www.springframework.org/schema/context/spring-context-4.0.xsd 15 http://www.springframework.org/schema/aop 16 http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 17 http://www.springframework.org/schema/tx 18 http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 19 http://www.springframework.org/schema/websocket 20 http://www.springframework.org/schema/websocket/spring-websocket.xsd"> 21 22 <context:property-placeholder ignore-unresolvable="true" location="classpath*:config.properties" /> 23 24 25 <!-- 使用Annotation自动注册Bean,Controllerller --> 26 <context:component-scan base-package="com.magicmed.ecg" use-default-filters="false"> <!--base-package 如果多个,用“,”分隔--> 27 <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> 28 </context:component-scan> 29 30 <!-- 自定义注解实现日志记录 --> 31 <aop:aspectj-autoproxy /> 32 33 <mvc:annotation-driven /> 34 35 36 <import resource="classpath:mybatis-spring.xml" /> 37 <import resource="classpath:mail-spring.xml" /> 38 <import resource="classpath:rabbitmq-spring.xml" /> 39 40 </beans>
spring.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/context 5 http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd"> 7 8 <bean id="propertyConfigurer" 9 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" > 10 <property name="locations" > 11 <list> 12 </list> 13 </property> 14 <property name="ignoreUnresolvablePlaceholders" value="true" /> 15 </bean> 16 17 18 <!-- 导入配置文件--> 19 <import resource="classpath*:mybatis-spring.xml" /> 20 <import resource="classpath*:mail-spring.xml" /> 21 <import resource="classpath*:rabbitmq-spring.xml" /> 22 23 </beans>
失效的@Value是Parser这个父类的一个属性上的注解,而Parser的两个子类Parser1与Parser2继承这个属性;我的目的就是先用Parser执行一定得判断逻辑——判断版本号,如果是版本1就用Parser1读取文件,如果是版本2就用Parser2读取文件。经过我的测试,我发现Parser使用fileRoot属性是不为null,也就是注入成功了,而Parser怎么也注入不成功,fileRoot的值为null。 代码如下:
1 // parse 2 @Component 3 public class Parser { 4 5 @Value("${fileRoot}") 6 protected String fileRoot; //文件根路径 7 8 9 protected String getFilePath(String appuserId, String uri) { 10 return fileRoot + appuserId + System.getProperty("file.separator")+ uri; 11 } 12 13 14 public Map<String, String> getXML_version(String appuserId, String uri) { 15 Element root = null; 16 17 try { 18 Document document = new SAXReader().read(new File(getFilePath(appuserId, uri) + ".xml")); 19 root = document.getRootElement(); //获取根节点元素对象 20 } catch (DocumentException e) { 21 e.printStackTrace(); 22 } 23 return root.element("XMLInfo").element("Version").getTextTrim(); 24 } 25 26 27 public Map<String, Object> read_xml(String appuserId, String uri) { 28 return null; 29 } 30 31 } 32 33 // parser1 34 @Component 35 public class Parser1 extends Parser { 36 37 @Override 38 public Map<String, Object> read_xml(String appuserId, String uri) { 39 try { 40 InputStream in = new FileInputStream(new File(getFilePath(appuserId, uri) + ".xml")); 41 } catch (IOException e) { 42 e.printStackTrace(); 43 } 44 /** 45 * 待处理的逻辑 46 */ 47 return null; 48 } 49 50 } 51 52 53 // parser2 54 @Component 55 public class Parser2 extends Parser { 56 57 @Override 58 public Map<String, Object> read_xml(String appuserId, String uri) { 59 try { 60 InputStream in = new FileInputStream(new File(getFilePath(appuserId, uri) + ".xml")); 61 } catch (IOException e) { 62 e.printStackTrace(); 63 } 64 /** 65 * 待处理的逻辑 66 */ 67 return null; 68 } 69 70 }
1 @Service 2 public class testServiceImpl implements testService { 3 4 @Autowired 5 private Parser parser; 6 7 public Integer test(String id, String uri) { 8 9 Map<String,String> versionMap = parser.getXML_version(id,uri); 10 if(versionMap.get("mv").equals("1")){ 11 parser = new Parser1(); 12 }else if(versionMap.get("mv").equals("2")){ 13 parser = new Pparser2(); 14 } 15 16 parser.read_xml(id,uri); 17 18 return null; 19 } 20 21 }
刚开始我也怀疑配置文件,也怀疑缓存的问题。后来我在网上查阅资料,找到这样一段话,茅塞顿开:
原因是如果有注入bean的那个类,在被其他类作为对象引用的话(被调用)。这个被调用的类也必须选择注解的方式,注入到调用他的那个类中,不能用 new出来做对象,new出来的对象再注入其他bean就会 发生获取不到的现象。所以要被调用的javabean,都需要@service,交给Spring去管理才可以,这样他就默认注入了。
于是我把代码改成如下形式,注入成功了。
1 @Service 2 public class testServiceImpl implements testService { 3 4 @Autowired 5 private Parser parser; 6 7 @Autowired 8 private Parser1 parser1; 9 10 @Autowired 11 private Parser2 parser2; 12 13 14 public Integer test(String id, String uri) { 15 16 Map<String,String> versionMap = parser.getXML_version(id,uri); 17 if(versionMap.get("mv").equals("1")){ 18 parser = parser1; 19 }else if(versionMap.get("mv").equals("2")){ 20 parser = parser2; 21 } 22 23 parser.read_xml(id,uri); 24 25 return null; 26 } 27 28 }