Spring 普通類與工具類呼叫service層
在Spring MVC中,Controller中使用service只需使用註解@Resource/@Autowired就行,但是一般類(即不使用@Controller註解的類)要用到service時,Spring中的Service不是你想new就能new的,因為通過new例項化的物件脫離了Spring容器的管理,獲取不到註解的屬性值,所以會是null,就算呼叫service的類中有@Component註解加入了Spring容器管理,也還是null.
例項:
- @Component
- publicclass Test {
- @Resource(name = "testServiceImpl")
- private
- public Test() {
- }
- publicvoid run() {
- System.out.println("****");
- System.out.println(testService);
- }
- }
在Controller裡 new 這個物件
- Test test = new Test();
- test.run();
可用如下方法:
一、普通類與工具類共同的解決方法:
這裡的普通類指的:是不在spring容器管理下的類,是通過new 來例項化的類。
1、SpringContextUtil
package com.test.framework.utils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public classSpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; // Spring應用上下文環境 // 下面的這個方法上加了@Override註解,原因是繼承ApplicationContextAware介面是必須實現的方法 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { return applicationContext; } public static Object getBean(String name) throws BeansException { return applicationContext.getBean(name); } public static Object getBean(String name, Class requiredType) throws BeansException { return applicationContext.getBean(name, requiredType); } public static boolean containsBean(String name) { return applicationContext.containsBean(name); } public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { return applicationContext.isSingleton(name); } public static Class getType(String name) throws NoSuchBeanDefinitionException { return applicationContext.getType(name); } public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { return applicationContext.getAliases(name); } }
2、Spring的配置檔案application.xml中進行如下配置
<bean id="SpringContextUtil" class="com.test.framework.utils.SpringContextUtil" scope="singleton"></bean>
3、使用
DictService dictService = (DictService) SpringContextUtil.getBean("dictService");
List<dict> dict = (List<dict>) dictService.findByHQL(hql);
二、工具類單獨的解決方法
如果我們要在我們自己封裝的Utils工具類中或者非controller普通類中使用@Autowired註解注入Service或者Mapper介面,直接注入是不可能的,因為Utils使用了靜態的方法,我們是無法直接使用非靜態介面的,當我們遇到這樣的問題,我們就要想辦法解決了。
Spring Bean初始化和銷燬Bean的方式雖然後三種,但是第三種是不符合這個,因為Utils是不用繼承或者宣告介面的,
1、註解方式:
- @Component
- publicclass TestUtils {
- @Autowired
- private ItemService itemService;
- @Autowired
- private ItemMapper itemMapper;
- publicstatic TestUtils testUtils;
- @PostConstruct
- publicvoid init() {
- testUtils = this;
- }
- //utils工具類中使用service和mapper介面的方法例子,用"testUtils.xxx.方法" 就可以了
- publicstaticvoid test(Item record){
- testUtils.itemMapper.insert(record);
- testUtils.itemService.queryAll();
- }
- }
我們在init方法中使用以下註解就可以了,時間上這個init()的方法是可以自己隨便定義的,注意:inti()方法裡面只需要一行程式碼,跟我這樣的就絕對ok了,不用看網上其他人瞎掰!
2、xml配置方式:
我們可以把init()方法上的@PostConstruct註解去掉,在spring-comtext.xml中配置以下bean就好了,裡面什麼內容都不用寫,是不是很簡單?
- <beanid="testUtils"class="這裡寫utils類的包全路徑名"init-method="init"></bean>
附錄: 另外一種Spring bean的初始化和銷燬方式
實現InitializingBean, DisposableBean這兩個介面,並複寫afterPropertiesSet()和destroy()方法
示例程式碼如下:
- publicclass InitializingDisposableInit implements InitializingBean,
- DisposableBean {
- @Override
- publicvoid destroy() throws Exception {
- System.out.println("執行InitializingDisposableInit: destroy");
- }
- @Override
- publicvoid afterPropertiesSet() throws Exception {
- System.out.println("執行InitializingDisposableInit: afterPropertiesSet");
- }
- publicstaticvoid main(String[] args) {
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
- "classpath:beans-impl.xml");
- context.close();
- }