当前位置: 首页 > 知识库问答 >
问题:

获取抽象类上的自定义bean

马梓
2023-03-14

我有这样一个类,它从application.properties获取配置,以创建连接到数据库的驱动程序(im使用jdbc连接到我的数据库):

@Component
public class JdbcConfiguration {

@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String user;
@Value("${spring.datasource.driver-class-name}")
private String driver;
@Value("${spring.datasource.password}")
private String password;

@Bean
public void setUpDriver() {
    DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
    driverManagerDataSource.setUrl(url);
    driverManagerDataSource.setUsername(user);
    driverManagerDataSource.setPassword(password);
    driverManagerDataSource.setDriverClassName(driver);
  }
}

我还有一个名为JdbcDao的抽象类来创建连接到数据库所必需的所有工具:

@Component
public abstract class JdbcDao {

@Autowired
private ApplicationContext context;

@Autowired
private JdbcConfiguration jdbcConfiguration;

private JdbcTemplate jdbcTemplateObject;

public JdbcDao() {
    JdbcConfiguration a = context.getBean(JdbcConfiguration.class);
    DriverManagerDataSource driver = context.getBean(DriverManagerDataSource.class);

    this.jdbcTemplateObject = new JdbcTemplate(driver);
}

public JdbcTemplate getJdbcTemplateObject() {
    return jdbcTemplateObject;
 }
}

然后,我有了那个jdbc抽象类的具体表示:

public class JdbcUserDao extends JdbcDao implements UserDao {

public JdbcUserDao() {
    super();
}

@Override
public void save(User entity) {
    System.out.println("save");
}

@Override
public void delete(User entity) {
    System.out.println("delete");
}

@Override
public User findById(Long id) {
    return getJdbcTemplateObject().queryForObject(QueryConstants.User.GET_USER_BY_ID, new Object[] { id },
            new UserMapper());
}
}

但是当我做新的JdbcUserDao()时,我有一个NPE,因为应用程序上下文没有被注入,这会在尝试获取自定义bean时导致一个空指针。

  • 堆栈跟踪:
  • 实例化JDBCUserDAO的类:

DatabaseFactory:

@Value("${connection.type}")
private String connectionType;

public UserDao getConnectionType() {
    DatabaseConnectionType type = DatabaseConnectionType.getDatabaseConnectionType(connectionType);
    switch(type) {
        case JDBC_CONNECTION:
           return new JdbcUserDao();
        case JPA_CONNECTION:
           return new JpaUserDao();
        default:
            throw new NoDatabaseConfigExceotion(); //EXAMPLE EXCEPTION
    }
}

>

  • 用户服务:

    @Service
     public class UserService implements IUserService {
    
    @Autowired
    DatabaseFactory userDatabaseConnection;
    
    @Override
    public User getUser(Long id) {
        return userDatabaseConnection.getConnectionType().findById(id);
    }
    }
    
  • 共有1个答案

    柴星津
    2023-03-14

    如果您真的按照您所说的那样做,执行new JdbcUserDao(),那么这就是为什么ApplicationContext Context没有填充到该对象中的原因。不能通过new实例化Spring Bean(即Spring托管/注入实例)。如果您这样做,那么Spring将不知道它的任何信息,因此不会扫描它,因此类或其子类上的任何注释都不会对类的实例产生任何影响。您需要获取应用程序的BeanFactory,然后通过向BeanFactory请求类实例Bean的副本来实例化该类。这个类必须已经注册到Spring中,这样它才能知道它并实例化它。

    除非您是在XML中这样做的,否则我看不到jdbcuserdao已经作为Spring bean注册到Spring中。您需要对它进行注释,使其成为Spring Bean,然后通过调用BeanFactory获得它的一个实例。只有这样,类中的注释才会生效,并且该实例才会被Spring连接起来。

     类似资料:
    • 也许我跑错了方向,但我有一个元素列表,我想读。 我有一个抽象基类,让我们称之为: 现在我有两个可能的实现:

    • 问题内容: 是否可以在不添加抽象方法的情况下定义抽象类? 问题答案: 当然。 声明一个类抽象仅意味着您不允许自己对其进行实例化。 声明方法抽象意味着子类必须提供该方法的实现。 这两个是单独的概念,尽管很明显,您不能在非抽象类中使用抽象方法。您甚至可以使用带有方法的抽象类,但绝不能相反。

    • 我的大多数测试都是在扩展BaseReport的具体类上进行的,没有任何问题: 这适用于所有扩展baseReport的类的autowiring。但是我还需要autowire抽象类本身BaseReport,以测试export()方法。 当我试图运行它时,我得到了臭名昭著的: 干杯。

    • 问题内容: 在Java中,我可以在抽象类中获取扩展它的具体类的实例吗? 问题答案: 是的,您可以致电。这将为您提供运行时类型为的实例。 如果只需要类的名称,则可以使用。 最后,还有和。我一直使用前者来打印可读的类名以记录文件等。

    • 我正在努力理解被称为抽象的OOP基本概念。当我说“理解”时,我的意思不仅仅是学习一个定义,而是真正有一个深刻的理解。 在网上,我看到了许多定义,如: 隐藏底层实现并提供高层规范 和 注重基本品质,而不是具体的例子。 我知道iPhone按钮是一个很好的抽象例子,因为作为一个用户,我不需要知道屏幕是如何显示的,我所需要知道的就是按下按钮。 关于抽象,你认为以下结论如何: 抽象需要对象的许多具体实例,并

    • 问题内容: 我有一个像这样的课程: 但是编译器说:。 我如何获得的课程? 问题答案: 绝对有可能将其提取出来,因为它不是在运行时定义的,而是在编译时由定义的。 这是一个启动示例,您可以如何在抽象类的构造函数中提取所需的泛型超类型,同时考虑子类的层次结构(以及在无需显式提供类型的情况下将其应用于泛型方法的实际用例)):