众所周知,spring是目前来说最好的java框架,使用spring开发程序省去了我们很多繁杂的工作,比如说自己管理bean声明周期,依赖注入等。我们平时除了依赖框架开发之外,spring同时提供了一些接口供开发者使用,这样的话我们的自己的程序就可以交给spring容器管理,或者说使用spring的很多功能,常见的ApplicationContext和InitialingBean等,接下来将简单介绍ApplicationContext的应用场景和使用姿势:
一、概念描述
package org.springframework.context;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @see ResourceLoaderAware
* @see ApplicationEventPublisherAware
* @see MessageSourceAware
* @see org.springframework.context.support.ApplicationObjectSupport
* @see org.springframework.beans.factory.BeanFactoryAware
*/
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
从源码中可以看到,ApplicationContextAware接口只有一个方法setApplicationContext,实现了该接口的子类在spring容器启动初始化的时候获取上下文信息ApplicationContext,通过ApplicationContext可以获取Spring容器内的很多信息(比如获取所有已经注册到spring容器的bean)
二、创建maven项目&添加基本依赖
创建简单的maven项目并添加一下依赖:
<!-- spring-beans依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- spring-context依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
三、编写上下文工具类并注册到spring容器
1.首先我们编写上下文操作的工具类:
package com.typhoon.demo1.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.util.Map;
/**
* spring上下文工具类
* <p>可以使用该类获取spring的信息(比如所有已经注册到spring容器的bean)</p>
*
* @author Typhoon
* @date 2017-08-28 16:30 Monday
* @since V1.3.1
*/
public class SpringContextUtil implements ApplicationContextAware {
/**
* 将applicationContext设置成静态属性,一次初始化后就任何地方就可以使用
*/
private static ApplicationContext applicationContext;
/*
* 该方法在spring初始化该bean的时候触发,触发之后该类的静态属性ApplicationContext就获得了spring的上下文信息
*
* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* 获取spring上下文信息
*
* @return
*/
public static ApplicationContext getApplicationContext() {
checkApplicationContext();
return applicationContext;
}
/**
* 根据名称获取bean
*
* @param name
* @return
*/
public static <T> T getBean(String name) {
checkApplicationContext();
return (T) applicationContext.getBean(name);
}
/**
* 根据类型获取bean(如果一个接口有多个实现这种方式获取会有问题)
*
* @param requiredType
* @return
*/
public static <T> T getBean(Class<T> requiredType) {
checkApplicationContext();
return applicationContext.getBean(requiredType);
}
/**
* 检查是否包含name对应的bean
*
* @param name
* @return
*/
public static boolean containsBean(String name) {
checkApplicationContext();
return applicationContext.containsBean(name);
}
/**
* 获取对应类型的所有bean列表
*
* @param requiredType
* @return
*/
public static <T> Map<String, T> getBeans(Class<T> requiredType) {
checkApplicationContext();
return applicationContext.getBeansOfType(requiredType);
}
/**
* 根据名称和类型获取bean
* @author Typhoon
* @param name
* @param clazz
* @return
*/
public static <T> T getBean(String name,Class<T> clazz) {
checkApplicationContext();
return applicationContext.getBean(name, clazz);
}
/**
* 清空上下文信息
*/
public static void cleanApplicationContext() {
applicationContext = null;
}
/**
* 检查上下文是否注册成功
*/
private static void checkApplicationContext() {
if (applicationContext == null)
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextUtil");
}
}
代码中最重要的一个方法就是对ApplicationContextAware的实现,通过此方法我们直接将spring上下文信息赋值给该工具类的静态属性。
上述的工具类提供了一些常用的操作方法,如果不能满足你的需求可以自己做扩展.
2.将工具类注册到spring容器:
在src/main/resource目录下创建spring.xml并添加如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean class="com.typhoon.demo1.util.SpringContextUtil" />
</beans>
四、编写供上下文工具类操作的bean并注入spring容器
1.编写接口
编写一个简单的service接口:
package com.typhoon.demo1.service;
import com.typhoon.demo1.entity.User;
public interface UserService {
User getById(Long id);
}
2.编写接口实现
对上述service接口编写简单的实现类:
package com.typhoon.demo1.service.impl;
import com.typhoon.demo1.entity.User;
import com.typhoon.demo1.service.UserService;
public class UserServiceImpl implements UserService {
public User getById(Long id) {
User u = new User();
u.setId(1L);
u.setAge(27);
u.setName("typhoon");
return u;
}
}
3.将service注册到spring容器中
<bean id="userService" class="com.typhoon.demo1.service.impl.UserServiceImpl" />
五、编写单元测试
编写一个单元测试类当做消费方,并且运行观察结果:
package com.typhoon.demo1.consumer;
import java.util.Map;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.typhoon.demo1.service.UserService;
import com.typhoon.demo1.util.SpringContextUtil;
public class ApplicationContextConsumer {
public static void main(String[] args) {
new ClassPathXmlApplicationContext("spring.xml").start();
UserService service1 = SpringContextUtil.getBean(UserService.class);
System.out.println("方式1结果:" + ToStringBuilder.reflectionToString(service1.getById(1L)));
UserService service2 = SpringContextUtil.getBean("userService");
System.out.println("方式2结果:" + ToStringBuilder.reflectionToString(service2.getById(1L)));
UserService service3 = SpringContextUtil.getBean("userService", UserService.class);
System.out.println("方式3结果:" + ToStringBuilder.reflectionToString(service3.getById(1L)));
Map<String, UserService> beans = SpringContextUtil.getBeans(UserService.class);
for(Map.Entry<String, UserService> entry : beans.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
运行后看到如下结果:
可以看到通过上述运行结果,我们已经实现了通过上下文工具类操作spring容器中的bean.
总结
通过上述一系列配置和编码,我们已经实现了通过上下文工具类一次注册处处可以使用获取spring信息,该工具类在我们编写公共模块中需要操作db或者redis等第三方容器的时候特别方便,或者说不需要繁杂的spring配置的时候也可以使用.
本文分享自 PersistentCoder 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!