不加载,手动实例化Service

本文介绍了一种在Java应用中使用Spring框架进行Bean实例化的策略。通过定义BeanService和BeanUtil两个工具类,实现了按需加载Spring上下文中定义的Beans,并缓存已加载的Bean实例以提高后续获取Bean实例的效率。


//调用方法
private static IEntityService entityService=(IEntityService) BeanService.getBean("entityService");


BeanService里面的方法
private static Map<String, Object> beans;
static {
beans = new HashMap<String, Object>();
}
public static Object getBean(String beanName) {
if (beans.containsKey(beanName) && beans.get(beanName) != null) {
return beans.get(beanName);
}
Object bean = BeanUtil.getBean(beanName);
if (bean != null) {
beans.put(beanName, bean);
}
return bean;
}



BeanUtil里面的方法

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;
public class BeanUtil {
private static ClassPathXmlApplicationContext context;
private static String flagInit = "0";
/**
* 获取spring上下文
* @return 上下文容器
*/
private static ApplicationContext getContext() {
synchronized (flagInit) {
if ("0".equals(flagInit)) {
if (context == null) {
ClassPathXmlApplicationContext context1 = new ClassPathXmlApplicationContext("spring-config.xml", "spring-mvc.xml");//分别是Spring和MVC的配置文件
context = context1;
context.start();
}
flagInit = "1";
}
}
return context;

}

static {
getContext();
}


/**
* 获取bean
* @param beanName
* @return
*/
public static Object getBean(String beanName) {
if (StringUtils.isEmpty(beanName)) {
return null;
}
if (getContext() == null) {
return null;
}

return getContext().getBean(beanName);
}
}

<think>好的,用户现在问的是如何在Spring Boot中使用注解来获取Service的实例。之前他们已经问过关于配置加载的问题,现在转向了依赖注入的具体实现方式。首先,我需要确定用户对Spring框架的理解程度。他们可能已经知道使用@Autowired或@Resource这样的注解来注入Service,但现在想了解其他方法,可能是因为他们遇到了某些限制,或者想更深入地理解Spring的底层机制。 接下来,我需要回忆Spring中获取Bean的同方式。使用注解的话,常见的方法包括通过ApplicationContext直接获取、使用BeanFactory、或者手动注册并获取。此外,可能还需要考虑非Spring管理的场景,这时候可能需要手动创建实例,但通常Service是由Spring管理的,所以这种情况较少。 用户的需求可能包括希望避免注解带来的耦合,或者在某些无法使用注解的情况下(如传统的XML配置项目,或者需要动态获取Bean的情况)。需要确保回答覆盖同的方法,并解释它们的适用场景和优缺点。 然后要检查是否有遗漏的方式。例如,使用BeanFactoryAware接口,或者通过静态方法访问ApplicationContext。过,后者可能涉及到使用注解来初始化静态的ApplicationContextHolder,但如果在配置类中使用注解的话,可能需要通过其他方式注册这个Holder。 另外,需要提醒用户注意直接获取Bean可能带来的问题,比如破坏IoC容器的控制反转原则,导致代码更难测试和维护。所以虽然提供了方法,也要给出适当的警告和使用建议。 最后,确保回答结构清晰,分点说明,每个方法都有示例代码和说明,让用户能够逐步理解和实现。同时保持语言简洁,避免技术术语过于复杂,但又要准确无误。</think>在 Spring Boot 中,如果使用注解(如 `@Autowired` 或 `@Resource`),可以通过以下方式获取 Service 实例: --- ### **1. 通过 `ApplicationContext` 直接获取** Spring 的核心容器 `ApplicationContext` 提供了直接获取 Bean 的接口。需要先获取 `ApplicationContext` 实例,再通过名称或类型获取 Bean。 #### **实现方式**: ```java import org.springframework.context.ApplicationContext; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MainApp { private static ApplicationContext context; public static void main(String[] args) { context = SpringApplication.run(MainApp.class, args); // 获取 Service 实例 MyService myService = context.getBean(MyService.class); myService.doSomething(); } } ``` #### **关键方法**: - `getBean(Class<T> clazz)`:按类型获取 Bean。 - `getBean(String name)`:按 Bean 名称获取。 --- ### **2. 实现 `ApplicationContextAware` 接口** 通过实现 `ApplicationContextAware` 接口,可以直接注入 `ApplicationContext`,再通过它动态获取 Bean。 #### **步骤**: 1. 创建一个工具类实现 `ApplicationContextAware`: ```java import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) { context = applicationContext; } public static <T> T getBean(Class<T> clazz) { return context.getBean(clazz); } } ``` 2. 在代码中直接调用: ```java // 获取 Service 实例 MyService myService = SpringContextHolder.getBean(MyService.class); ``` --- ### **3. 使用 `BeanFactory` 手动获取** 通过 `BeanFactory` 接口(`ApplicationContext` 的父接口)直接获取 Bean,但需要初始化工厂。 #### **示例**: ```java import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; public class ManualBeanLoad { public static void main(String[] args) { BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml")); MyService myService = (MyService) factory.getBean("myService"); myService.doSomething(); } } ``` **注意**:此方法需配合 XML 配置(如 `beans.xml`),在 Spring Boot 中较少使用。 --- ### **4. 通过静态工厂方法** 手动注册 Bean 到容器中,再通过工厂方法获取实例。 #### **示例**: 1. 在配置类中定义 Bean: ```java @Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } } ``` 2. 手动获取 Bean: ```java ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); MyService service = context.getBean(MyService.class); ``` --- ### **5. 非 Spring 管理的场景(推荐)** 如果 Service 未托管给 Spring,可直接通过 `new` 关键字实例化,但**会失去依赖注入和 Spring 管理的能力**: ```java MyService myService = new MyServiceImpl(); ``` --- ### **总结** | 方法 | 适用场景 | 优点 | 缺点 | |--------------------------|-----------------------------------|-------------------------|------------------------------------| | `ApplicationContext` | 需要在启动类或静态上下文中获取 | 直接、灵活 | 需手动管理上下文 | | `ApplicationContextAware`| 全局获取 Bean | 代码简洁,可复用 | 需实现接口,增加耦合 | | `BeanFactory` | 传统 XML 配置项目 | 兼容旧系统 | 配置复杂,适合 Spring Boot | | 静态工厂方法 | 手动控制 Bean 初始化 | 灵活性高 | 需显式配置,代码侵入性强 | --- ### **注意事项** - **避免滥用**:直接获取 Bean 可能破坏 Spring 的依赖注入原则,导致代码耦合。 - **生命周期管理**:手动获取的 Bean 需自行处理作用域(如单例、原型)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值