记录一下解决private方法中@Autowired无法注入问题

本文介绍了如何处理在Spring框架中,@Autowired注解无法在private方法内正常注入bean的问题。通过创建一个SpringBeanFactoryConfig配置类,实现ApplicationContextAware接口,静态持有ApplicationContext,然后在private方法内通过该配置类获取所需的bean。这种方法提供了一种在私有方法中获取bean的解决方案。

记录一下解决private方法中@Autowired无法注入问题

添加配置类

public class SpringBeanFactoryConfig implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    /**
     * 重写setApplicationContext方法,把ApplicationContext对象inject到当前类中作为一个静态成员变量。
     */
    public void setApplicationContext(ApplicationContext appCtx) throws Exception {
        applicationContext = appCtx;
    }

    /**
     * 获取ApplicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * @return 返回一个bean对象
     */
    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }

    /**
     * @return 返回一个bean对象
     */
    public static Object getBean(Class c) {
        return applicationContext.getBean(c);
    }
}

加入一个bean

<bean id="springBeanFactoryConfig " class="com.xxx.xxx.SpringBeanFactoryConfig" />

private修饰方法中获取bean,并调用接口

xxxService service = (xxxService)SpringBeanFactoryConfig.getBean(xxxService.class);

原文地址:https://www.it610.com/article/1281724921046646784.htm

### Spring Boot中EntityManagerFactory创建失败的问题及动态注入Repository到Map的实现 #### 问题分析 用户遇到了`BeanCreationException`异常,其根本原因是`entityManagerFactory`在初始化时发生错误。具体表现为`PersistenceException`和`JDBCConnectionException`,这表明数据库连接存在问题[^1]。此外,用户希望实现动态注入所有Repository到Map中,并通过反射机制完成特定操作。 以下是针对上述问题的专业解决方案。 --- #### 解决方案 #### 1. **解决EntityManagerFactory创建失败的问题** - **检查数据库连接配置**:确保`application.properties`中的数据库配置正确无误。例如: ```properties spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/db_name?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=root ``` 如果使用的是其他数据库(如PostgreSQL或Oracle),需调整驱动类名和URL格式[^2]。 - **验证数据库服务状态**:确认数据库服务已启动且可访问。可以通过以下命令测试: ```bash telnet localhost 3306 ``` 如果无法连接,请检查数据库IP、端口、防火墙设置等。 - **增加连接池容错配置**:为避免因网络波动导致连接失败,可以增加HikariCP的超时配置: ```properties spring.datasource.hikari.connection-timeout=20000 spring.datasource.hikari.maximum-pool-size=10 ``` - **启用SQL日志调试**:通过开启日志记录,定位具体问题: ```properties spring.jpa.show-sql=true logging.level.org.hibernate.SQL=DEBUG logging.level.org.springframework.jdbc.core=TRACE ``` --- #### 2. **动态注入所有Repository到Map中** 为了实现动态注入所有Repository到Map中,可以通过Spring的反射机制完成。以下是具体实现: ```java import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.util.Map; @Component public class RepositoryLoader implements ApplicationContextAware { private Map<String, Object> repositoryMap; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // 获取所有以"Repository"结尾的Bean this.repositoryMap = applicationContext.getBeansWithAnnotation(org.springframework.stereotype.Repository.class); } public Map<String, Object> getRepositories() { return repositoryMap; } } ``` #### 3. **通过反射调用Repository方法** 假设需要调用某个Repository的方法`setShiti`,可以通过反射实现: ```java import java.lang.reflect.Method; public class ReflectionUtil { public static void invokeMethod(Object bean, String methodName, Object... args) throws Exception { Class<?> clazz = bean.getClass(); Method method = clazz.getMethod(methodName, new Class[]{args.getClass()}); method.invoke(bean, args); } } ``` 结合上述代码,可以通过以下方式调用: ```java RepositoryLoader loader = new RepositoryLoader(); Map<String, Object> repositories = loader.getRepositories(); for (Map.Entry<String, Object> entry : repositories.entrySet()) { try { ReflectionUtil.invokeMethod(entry.getValue(), "setShiti", "exampleValue"); } catch (Exception e) { e.printStackTrace(); } } ``` --- #### 注意事项 - **事务管理**:确保在调用Repository方法时,事务管理器已正确配置。否则可能导致数据一致性问题。 - **性能优化**:如果Repository数量较多,建议对`repositoryMap`进行懒加载,避免一次性加载过多Bean影响启动速度。 - **安全性**:反射调用可能带来安全风险,建议仅在受控环境中使用。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值