随手记录4:spring上下文ApplicationContext 获取和使用;
简介
项目中基本上好多对象都是交给spring管理的;
但是有些静态的工具类中想获取该对象又不能通过 @Autowired直接注入;
或者有些方法里面需要使用到spring托管的对象; 可以通过ApplicationContext 直接获取;
关于ApplicationContext 获取
获取 方式一:
基于springboot有最简单的获取方式 main方法启动类的入口可以直接获取到applicationContext
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) throws Exception {
ApplicationContext applicationContext = SpringApplication.run(MainApplication.class, args);
}
}
获取方式二:
通过实现ApplicationContextAware 接口然后实现setApplicationContext 方法;
@Component
public class SpringAware implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
*根据spring托管对象的beanName获取实力对象;
* @author khy
* @createTime 2020年9月3日下午1:47:03
* @param name
* @return
*/
public <T>T getBeanByName(String name){
return (T) applicationContext.getBean(name);
}
}
//上述类中属性可以定义成 private static ApplicationContext applicationContext;
//静态的,然后在当前方法里面可以通过静态方法获取我们需要的spring管理的各种service/mapper等内容;
关于ApplicationContext 使用
主要是通过spring上下文获取交给spring管理的bean;
还是通过前面写过的文章案例 FactoryBean 的使用
1.UserService .java
类中通过@service注解初始化对象
Service("userService")
public class UserService {
private String userName="UserService命名小康康";
public UserService() {
System.out.println(this);
System.out.println("UserService初始化");
}
private UserService(String userName) {
this.userName = userName;
}
public static UserService getInstance(String userName){
return new UserService(userName);
}
public String say(String detail) {
System.out.println("用户{"+userName+"} say{"+detail+"}");
return "say执行完毕";
}
}
2.FactoryBeanConfig .java
通过
@Configuration
public class FactoryBeanConfig {
@Bean
public UserServiceFactoryBean createUserFactoryBean (){
UserServiceFactoryBean bean = new UserServiceFactoryBean("createUserFactoryBean命名小康康");
System.out.println("createUserFactoryBean初始化");
return bean;
}
@Bean
public UserService createUserService (){
UserService bean = UserService.getInstance("createUserService命名小康康");
System.out.println("createUserService初始化");
return bean;
}
}
@RestController
@RequestMapping("/factory")
public class FactoryController {
@Autowired
private SpringAware springAware;
@Autowired
private UserServiceFactoryBean factoryBean;
@Autowired
private UserService userService;
@Autowired
private UserService createUserService;
@Autowired
private UserService createUserFactoryBean;
@RequestMapping("/test")
public String test() throws Exception{
System.out.println("///userService执行开始//");
String say = userService.say("注入的userService成功");
UserService getService = springAware.getBeanByName("userService");
say = getService.say("SpringAware获取的的userService成功");
System.out.println("///userService执行结束//");
System.out.println("///createUserService执行开始//");
say = createUserService.say("注入的createUserService成功");
UserService getService1 = springAware.getBeanByName("createUserService");
say = getService1.say("SpringAware获取的的createUserService成功");
System.out.println("///createUserService执行结束//");
System.out.println("///createUserFactoryBean执行开始//");
say = createUserFactoryBean.say("注入的createUserFactoryBean成功");
UserService getService2 = springAware.getBeanByName("createUserFactoryBean");
say = getService2.say("SpringAware获取的的createUserFactoryBean成功");
System.out.println("///createUserService执行结束//");
/**
* 上面都是直接获取的UserService
* UserService createUserFactoryBean 是通过工厂UserServiceFactoryBean创建的
* 但是如果想拿到工厂类本身则通过ApplicationContext 获取的时间需要添加&
*/
System.out.println("///工厂类UserServiceFactoryBean执行开始//");
say = factoryBean.getObject().say("注入的createUserFactoryBean的UserServiceFactoryBean成功");
UserServiceFactoryBean getFactory = springAware.getBeanByName("&createUserFactoryBean");
getFactory.getObject().say("SpringAware获取的的UserServiceFactoryBean成功");
System.out.println("///工厂类UserServiceFactoryBean执行结束//");
return "执行完毕了"+say;
}
}
结论
通过applicationContext 获取spring中托管的对象内容;
案例中是通过spring托管的beanName 来获取的指定对象的内容
案例中通过方法获取的对象和通过@Autowired注入的(beanName相同的情况下是同一个内存对象)
******想获取FactoryBean 本身的对象则需要在beanName前面添加&
例如本文的案例中的 UserServiceFactoryBean 是UserService的工厂类
在FactoryBeanConfig 初始化,虽然看似初始化的UserServiceFactoryBean ,但是其实获取的到的是
其实是目标对象内容, 所以applicationContext 通过beanName=createUserFactoryBean 获取到的是UserService对象; 要获取UserServiceFactoryBean类则beanName=&createUserFactoryBean
@Bean
public UserServiceFactoryBean createUserFactoryBean (){
UserServiceFactoryBean bean = new UserServiceFactoryBean("createUserFactoryBean命名小康康");
System.out.println("createUserFactoryBean初始化");
return bean;
}