作为初学者来说,无论spring的控制反转和依赖注入大家都已耳熟能详,但真正能够熟练运用的依然少之又少。springmvc、struts2、spring、hibernate、Jpa、mybatis、mybatisplus这些技术组合,都依然体现着分层的思想,由最初的三层架构来说,spring似乎充当着实例化工厂的角色。但很多小白都太过熟悉了,以致潜意识认为项目就这么些@controller、@service@dao组合就好了,复杂算法就写前端吧。如是Spring在我们设计的项目中总能登堂入室,粉墨登场。如我一样,身陷囹圄的怕是大有人在。
JAVA的世界是对象,我们的代码是该有灵魂的。
讲讲前几天遇到的事情。在为老项目添加一些新功能的时候,我习惯性的使用@Autowired去注入JdbcTemplate模版对象,但调试时发现它一直是NULL
@Autowired
@Qualifier("jdbcTemplate2")
protected JdbcTemplate jdbcTemplate2;
//获取datameasuretemplate
public NodeList<DataMeasure> getDataMeasureTemplate(){
return ((DataMeasureTemplate)SpringUtil.getBean("datameasuretemplate")).dataMeasures;
}
//获取表索引名称
public String getTableIndex() {
return AqmsConstantUtil.AQMS_REAL_TALBE_INDEX;
}
为什么呢,是它没实例化吗?(default-lazy-init="true"懒加载对实例化问题是没有影响的,之前有过误解。)
使用实现ApplicationContextAware的方式获取spring容器中的bean,发现是能够拿得到的,说明实例化了。
经过多次测试,发现自动注入的源和目标都必须存在于Spring体系当中,交由spring管理的。@autowired下的是源,你注入的地方类是目标位置,但往往我并不希望目标类也交由spring实例化,因为代码结构可能存在于比较深的层次当中。
解决方案是:使用MethodInvokingFactoryBean静态注入你的对象。
MethodInvokingFactory Bean类,可注入方法返回值。 MethodInvokingFactoryBean用来获得某个方法的返回值,该方法既可以是静态方法,也可以是实例方法。该方法的返回值可以注入bean实例属性,也可以直接定义成bean实例。
<bean id="aqmsService" class="com.fpi.prd.aqms.service.impl.AqmsServiceImpl">
</bean>
<bean id="aqmsServerFactorty"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod"
value="com.fpi.prd.aqms.utils.AqmsServiceUtil.setService" />
<property name="arguments" ref="aqmsService" />
</bean>
public final class AqmsServiceUtil {
private static AqmsService service;
public static void setService(AqmsService service) {
AqmsServiceUtil.service = service;
} }
现在你可以通过工具类去获得service对象而不必担心工具类或其上层类是否也存在于spring体系当中。