2010-07-16 23 views
5

Tôi đang cố gắng sử dụng chú thích @Configuration để kết nối ứng dụng của mình nhưng tôi tiếp tục nhận được một NullPointerException trong một trong các trình khởi tạo vì bean nó đề cập đến chưa được khởi tạo (tôi nghĩ). Tôi đã thử chỉ định trong web.xml chỉ là lớp cấu hình 'root' và cũng đã thử thực hiện quét gói và dường như không hoạt động.Làm cách nào để đảm bảo cấu hình phụ thuộc được khởi tạo với chú thích Spring @Configuration?

Xin lỗi về kết xuất mã lớn. Tôi đã cố gắng tạo ra một nhóm các lớp học đơn giản hơn nhiều để tái tạo vấn đề, nhưng tất nhiên, khi tôi làm điều đó, mọi thứ đều hoạt động tốt. Dưới đây là lớp học của tôi (nhập khẩu elided):

DataSourceConfig.java:

@Configuration 
public class DataSourceConfig { 

    public DataSourceConfig() { 
     System.err.println("DataSourceConfig constructed..."); 
    } 

    @Bean 
    public DataSource dataSource() { 
     BasicDataSource bean = new BasicDataSource(); 
     bean.setDriverClassName("com.mysql.jdbc.Driver"); 
     bean.setUrl("jdbc:mysql://localhost:3306/observation"); 
     bean.setUsername("observation"); 
     bean.setPassword("*******"); 
     bean.setInitialSize(1); 
     bean.setMaxActive(5); 
     bean.setTestOnBorrow(true); 
     System.err.println("dataSource bean initialized: " + bean.toString()); 
     return bean; 
    } 
} 

HibernateConfig.java

@Configuration 
@Import(DataSourceConfig.class) 
public class HibernateConfig { 

    public HibernateConfig() { 
     System.err.println("HibernateConfig constructing..."); 
    } 

    @Autowired 
    private DataSourceConfig dataSourceConfig; 

    @Bean 
    protected NamingStrategy namingStrategy() { 
     return new ImprovedNamingStrategy(); 
    } 

    private AnnotationSessionFactoryBean sessionFactoryBean = null; 

    @Bean 
    @DependsOn("dataSourceConfig") 
    public AnnotationSessionFactoryBean sessionFactory() { 
     if (sessionFactoryBean == null) { 
      sessionFactoryBean = new AnnotationSessionFactoryBean(); 
NPE Here--> sessionFactoryBean.setDataSource(dataSourceConfig.dataSource()); 
      sessionFactoryBean.setSchemaUpdate(true); 
      sessionFactoryBean.setNamingStrategy(namingStrategy()); 
      sessionFactoryBean.setPackagesToScan(new String[] { 
        "com.newco.observations.domain", 
        "com.newco.observations.domain.*" }); 
      Properties props = new Properties(); 
      props.setProperty("hibernate.default_schema", "observation"); 
      props.setProperty("hibernate.dialect", 
        "org.hibernate.dialect.MySQLDialect"); 
      props.setProperty("hibernate.show_sql", "true"); 
      sessionFactoryBean.setHibernateProperties(props); 
      System.err.println("sessionFactory initialized"); 
     } 
     return sessionFactoryBean; 
    } 

    @Bean 
    @DependsOn("dataSourceConfig") 
    public JdbcTemplate jdbcTemplate() { 
     return new JdbcTemplate(dataSourceConfig.dataSource()); 
    } 

    @Bean 
    @DependsOn("sessionFactory") 
    public ResourceTransactionManager txManager() { 
     HibernateTransactionManager bean = new HibernateTransactionManager(); 
     bean.setSessionFactory((SessionFactory) sessionFactory().getObject()); 
     return bean; 
    } 

    @Bean 
    @DependsOn("sessionFactory") 
    public HibernateTemplate hibernateTemplate() { 
     return new HibernateTemplate((SessionFactory) sessionFactory() 
       .getObject()); 
    } 
} 

DaoConfig.java:

@Configuration 
@Import(HibernateConfig.class) 
public class DaoConfig { 

    public DaoConfig() 
    { 
     System.err.println("DaoConfig constructing..."); 
    } 

    private @Autowired HibernateConfig hibernateConfig; 

    @Bean 
    @DependsOn("hibernateTemplate") 
    public PhenomenonGroupDao phenomenonGroupDao() 
    { 
     PhenomenonGroupDaoImpl bean = new PhenomenonGroupDaoImpl(); 
     bean.setHibernateTemplate(hibernateConfig.hibernateTemplate()); 
     return bean; 
    } 

    @Bean 
    @DependsOn("hibernateTemplate") 
    public PhenomenonDao phenomenonDao() 
    { 
     PhenomenonDaoImpl bean = new PhenomenonDaoImpl(); 
     bean.setHibernateTemplate(hibernateConfig.hibernateTemplate()); 
     return bean; 
    } 

    @Bean 
    @DependsOn("hibernateTemplate") 
    public DiscretePhenomenonDao discretePhenomenonDao() 
    { 
     DiscretePhenomenonDaoImpl bean = new DiscretePhenomenonDaoImpl(); 
     bean.setHibernateTemplate(hibernateConfig.hibernateTemplate()); 
     return bean; 
    } 


} 

Bạn có thể nhìn thấy từ các chú thích của System.err.println và @DependsOn là một kiểu viết về t mũ tôi đang làm.

tôi có thể cung cấp đầy đủ các bản ghi nếu nó hữu ích, nhưng đây là những gì tôi nghĩ là các dòng có liên quan (với định dạng nhỏ để làm cho nó dễ đọc hơn (có thể)):

  • 208 [Chủ đề-0 ] INFO org.springframework.context.annotation.ConfigurationClassEnhancer
  • Tăng cường thành công com.bjk.observation.server.config.DaoConfig; tăng cường tên lớp là: com.bjk.observation.server.config.DaoConfig $$ $$ EnhancerByCGLIB 96e1956
  • 229 [Chủ đề-0] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory
  • độc thân Pre-instantiating trong org.s[email protected]185572a: định nghĩa bean [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org. springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.annotation.internalPersistenceAnnotationProcessor, daoConfig, com.bjk.observation.server.config.DataSourceConfig # 0, dataSource, com.bjk.observation.server.config.HibernateConfig # 0, đặt tên trategy, sessionFactory, jdbcTemplate, txManager, hibernateTemplate, hiện tượngGroupDao, hiện tượngDao, discretePhenomenonDao]; thư mục gốc của hệ thống phân cấp nhà máy DaoConfig xây dựng ...
  • 252 [Chủ đề-0] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory
  • độc thân Phá hoại các org.s[email protected]185572a: định nghĩa bean [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.annotation .internalPersistenceAnnotationProcessor, daoConfig, com.bjk.observation.server.config.DataSourceConfig # 0, dataSource, com.bjk.observation.server.config.HibernateConfig # 0, nameingStrategy, sessionFactory, jdbcTemplate, txManager , hibernateTemplate, hiện tượngGroupDao, phenomenDao, discretePhenomenonDao]; gốc của phân cấp nhà máy
  • 253 [Thread-0] ERROR org.springframework.web.context.ContextLoader
  • Khởi tạo ngữ cảnh không thành công org.springframework.beans.factory.BeanCreationException: Lỗi tạo bean với tên 'daoConfig': Tiêm phụ thuộc tự động không thành công; ngoại lệ lồng nhau là org.springframework.beans.factory.BeanCreationException: Không thể autowire trường: private com.bjk.observation.server.config.HibernateConfig com.bjk.observation.server.config.DaoConfig.hibernateConfig; ngoại lệ lồng nhau là org.springframework.beans.factory.BeanCreationException: Lỗi khi tạo bean có tên 'com.bjk.observation.server.config.HibernateConfig # 0': Sự khởi tạo của bean không thành công; ngoại lệ lồng nhau là org.springframework.beans.BeanInstantiationException: Không thể khởi tạo lớp bean [com.bjk.observation.server.config.HibernateConfig]: Constructor đã ném ngoại lệ; lồng nhau ngoại lệ là java.lang.NullPointerException

Trả lời

2

Vấn đề, tôi tin là ở đây:

@Autowired 
private DataSourceConfig dataSourceConfig; 

Bạn đang không được để dây mình một cách rõ ràng với @Configuration lớp -annotated khác, nhưng đúng hơn là đậu mà họ sản xuất. Mùa xuân sẽ sắp xếp hệ thống ống nước cho bạn.

Vì vậy, thay thế các lĩnh vực trên với đơn giản:

@Autowired 
private DataSource dataSource; 

mùa xuân sẽ lấy DataSource từ DataSourceConfig và minh bạch tiêm nó vào lĩnh vực này.

Tương tự, thay thế

@Autowired 
private HibernateConfig hibernateConfig; 

với

@Autowired 
private HibernateTemplate hibernateTemplate; 

Bạn sẽ nhận thấy rằng @Configuration phong cách không cảm thấy như thoải mái khi làm việc với đậu nhà máy như AnnotationSessionFactoryBean, vì bạn thường phải gọi getObject() trên chính bạn. Đôi khi, sử dụng cấu hình XML sẽ tự nhiên hơn và trộn nó với kiểu cấu hình java.

+3

Tôi không biết tại sao điều đó sẽ giúp chính xác vì các lớp được đánh dấu bằng @Configuration được cho là hạt đậu theo đúng nghĩa của chúng. Tuy nhiên, tôi đã cố gắng như bạn đề nghị và mặc dù bản ghi lỗi của tôi là khác nhau, nó vẫn phải làm với đậu không nhận được khởi tạo theo thứ tự đúng. Tôi nhận thấy quan điểm của bạn về việc cấu hình không tốt cho các nhà máy hạt và trên thực tế, tôi đã giảm về cấu hình xml đáng tin cậy cũ, nhưng tôi vẫn muốn hiểu làm thế nào nó _supposed_ để làm việc. – jhericks

Các vấn đề liên quan