Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何正确地注入服务类而不获取nullpointer异常?_Java_Spring_Spring Boot_Jpa_Multi Tenant - Fatal编程技术网

Java 如何正确地注入服务类而不获取nullpointer异常?

Java 如何正确地注入服务类而不获取nullpointer异常?,java,spring,spring-boot,jpa,multi-tenant,Java,Spring,Spring Boot,Jpa,Multi Tenant,我正在开发一个Spring启动应用程序,我正在尝试将我的UserService类注入到我的TenantIdentifierResolver类中,因为我想使用createUser()方法。然而,我得到了一个空指针异常。由于某些原因,userService被设置为null,我在这里缺少什么 @Component public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver { public

我正在开发一个Spring启动应用程序,我正在尝试将我的UserService类注入到我的TenantIdentifierResolver类中,因为我想使用createUser()方法。然而,我得到了一个空指针异常。由于某些原因,userService被设置为null,我在这里缺少什么

@Component
public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver {

    public static final String DEFAULT_TENANT = "default_schema";

    private UserService userService;

    @Override
    public String resolveCurrentTenantIdentifier() {
        String tenant =  TenantContext.getCurrentTenant();
        if(tenant != null){
            userService.createUser(tenant);
            return tenant;
        } else {
            return DEFAULT_TENANT;
        }
    }

    @Override
    public boolean validateExistingCurrentSessions() {
        return true;
    }
}
我曾尝试使用@Autowired或进行构造函数注入,但随后出现以下错误:

应用程序上下文中某些bean的依赖关系形成一个循环:

┌─────┐
|  entityManagerFactory defined in class path resource [org/example/membership/config/HibernateConfig.class]
↑     ↓
|  tenantIdentifierResolver (field private org.example.membership.service.UserService org.example.membership.multitenancy.TenantIdentifierResolver.userService)
↑     ↓
|  userService defined in file [C:\project\Member\server\target\classes\org\example\membership\service\UserService.class]
↑     ↓
|  userRepository defined in org.example.membership.repository.UserRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration
↑     ↓
|  (inner bean)#18957a3d
└─────┘
这是我的用户服务课程

@Service
public class UserService {

    private UserRepository userRepository;
    private TenantService tenantService;

    public UserService(UserRepository repository, TenantService tenantService) {
        this.userRepository = repository;
        this.tenantService = tenantService;
    }

    @Transactional
    public User createUser(String tenant) {
        Tenant tenant = new Tenant();
        tenant.setTenantName(tenant);
        tenantService.initDatabase(tenant);
        return tenant ;
    }
}
@Configuration
public class HibernateConfig {
    @Autowired
    private JpaProperties jpaProperties;

    @Bean
    JpaVendorAdapter jpaVendorAdapter() {
        return new HibernateJpaVendorAdapter();
    }

        @Bean
        LocalContainerEntityManagerFactoryBean entityManagerFactory(
        DataSource dataSource,
        MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
        CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl
    ) {

        Map<String, Object> jpaPropertiesMap = new HashMap<>(jpaProperties.getProperties());
      jpaPropertiesMap.put(Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA);
      jpaPropertiesMap.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProviderImpl);       
      jpaPropertiesMap.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolverImpl);

        LocalContainerEntityManagerFactoryBean em = new 
LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("org.example*");
        em.setJpaVendorAdapter(this.jpaVendorAdapter());
        em.setJpaPropertyMap(jpaPropertiesMap);
        return em;
    }
}
这是我的HibernateConfig课程

@Service
public class UserService {

    private UserRepository userRepository;
    private TenantService tenantService;

    public UserService(UserRepository repository, TenantService tenantService) {
        this.userRepository = repository;
        this.tenantService = tenantService;
    }

    @Transactional
    public User createUser(String tenant) {
        Tenant tenant = new Tenant();
        tenant.setTenantName(tenant);
        tenantService.initDatabase(tenant);
        return tenant ;
    }
}
@Configuration
public class HibernateConfig {
    @Autowired
    private JpaProperties jpaProperties;

    @Bean
    JpaVendorAdapter jpaVendorAdapter() {
        return new HibernateJpaVendorAdapter();
    }

        @Bean
        LocalContainerEntityManagerFactoryBean entityManagerFactory(
        DataSource dataSource,
        MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
        CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl
    ) {

        Map<String, Object> jpaPropertiesMap = new HashMap<>(jpaProperties.getProperties());
      jpaPropertiesMap.put(Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA);
      jpaPropertiesMap.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProviderImpl);       
      jpaPropertiesMap.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolverImpl);

        LocalContainerEntityManagerFactoryBean em = new 
LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("org.example*");
        em.setJpaVendorAdapter(this.jpaVendorAdapter());
        em.setJpaPropertyMap(jpaPropertiesMap);
        return em;
    }
}
@配置
公共类HibernateConfig{
@自动连线
私人物业;
@豆子
JpaVendorAdapter JpaVendorAdapter(){
返回新的HibernateJavaEndorapter();
}
@豆子
LocalContainerEntityManagerFactoryBean entityManagerFactory(
数据源数据源,
MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl
) {
Map jpaPropertiesMap=newhashmap(jpaProperties.getProperties());
jpapPropertiesMap.put(Environment.MULTI_-TENANT,MULTI-tenancystategy.SCHEMA);
jpaPropertiesMap.put(Environment.MULTI_-TENANT_-CONNECTION_-PROVIDER,MULTI-tenantconnectionproviderImpl);
jpaPropertiesMap.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER,currentTenantIdentifierResolverImpl);
LocalContainerEntityManagerFactoryBean em=new
LocalContainerEntityManagerFactoryBean();
em.setDataSource(数据源);
em.setPackagesToScan(“org.example*”);
em.setJpaVendorAdapter(this.jpaVendorAdapter());
em.setJpaPropertyMap(jpaPropertiesMap);
返回em;
}
}

您没有注入依赖项。您应该使用构造函数注入:

private final UserService userService;

public TenantIdentifierResolver(UserService userService) {
    this.userService = userService;
}
@Autowired
private UserService userService;
或者,如果愿意,可以使用属性注入:

private final UserService userService;

public TenantIdentifierResolver(UserService userService) {
    this.userService = userService;
}
@Autowired
private UserService userService;

这里面临的问题称为循环依赖。当两个组件相互需要bean时,就会发生这种情况。Spring不知道先创建哪个。你可以在这里了解更多

Easiset解决方案是在其中一个组件中实现基于setter的自动布线

@Component
public class TenantIdentifierResolver {

   private UserService userService;

   public UserService userService() {
       return userService;
   }

   @Autowired
   public void setUserService(final UserService userService) {
       this.userService = userService;
   }
}

最后,您必须解决循环依赖关系,无论您使用什么注入类型,或者是否采用惰性注入等

目前,entityManagerFactory需要用户服务bean(通过tenantIdentifierResolver),而用户服务bean本身就需要entityManagerFactory。那是一个糟糕的架构。您可以从tenantIdentifierResolver中删除对userService的调用,或者对其进行更改,使其中不使用与JPA相关的功能(即,如果确实需要动态创建租户/用户,请在其中使用普通JDBC调用)。那么你已经打破了依赖循环,一切都应该正常

@Autowired
private UserService userService;

至于循环依赖性问题,我认为您应该尽量避免。

您在服务上是否尝试了
@Autowired
?目前根本没有注入。@Thomas是的,我试过了,但它给出了以下错误:“应用程序上下文中某些bean的依赖项形成了一个循环”显示您的UserService@EricSchaefer我已经用UserService类更新了我的初始帖子。您可以尝试使用字段/属性注入,也就是说,让
UserService
也使用
@Autowired
而不是构造函数注入。或者尝试将
@Lazy
添加到构造函数参数中。更多信息请参见此处:我已更新了我的初始帖子。我已经试着按照你的建议去做了,但是我得到了周期误差,正如你在上面看到的。我试着用谷歌搜索它,但我不确定我是否理解错误是什么。谢谢,但这并不能解决任何问题。。它仍然给出完全相同的周期误差。