Работа Autowired в Spring Data JPA

278
01 ноября 2017, 01:18

Как заставить работать Autowired, не создавая экземпляр класса сервиса из контекста? Использую Спринг Дата без Спринг Бут. Класс конфигурации:

@Configuration
@EnableJpaRepositories
public class SpringConfig {
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(com.mysql.jdbc.Driver.class.getName());
        dataSource.setUrl("jdbc:mysql://localhost:3306/kvi?useSSL=false");
        dataSource.setUsername("");
        dataSource.setPassword("");
        return dataSource;
    }
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        entityManagerFactoryBean.setJpaProperties(hibProperties());
        entityManagerFactoryBean.setPackagesToScan("repository", "models");
        return entityManagerFactoryBean;
    }
    private Properties hibProperties() {
        Properties jpaProperties = new Properties();
        jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        jpaProperties.setProperty("hibernate.hbm2ddl.auto", "update");
        jpaProperties.setProperty("hibernate.connection.useUnicode", "true");
        jpaProperties.setProperty("hibernate.connection.characterEncoding", "UTF-8");
        return jpaProperties;
    }
    @Bean
    public JpaTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return transactionManager;
    }
}

Репозиторий:

@Repository
public interface PersonRepository extends CrudRepository<Person, Long>{
}

Это сервис:

@Service
@Transactional
public class PersonService {
    @Autowired
    private PersonRepository personRepository;
    public Iterable<Person> findAll () {
        return personRepository.findAll();
    }
}

Ну и соотвественно есть ентити Person (листинг приводить не буду). Запуск из класса Main:

@ComponentScan
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        AutowireCapableBeanFactory autowireCapableBeanFactory = context.getAutowireCapableBeanFactory();
        PersonService ps = autowireCapableBeanFactory.createBean(PersonService.class);
        List <Person> pers = new ArrayList <>();
        Iterable<Person> findAll = ps.findAll();
        CollectionUtils.addAll(pers, findAll);
        for (Person p : pers) {
            System.out.println(p);
        }
    }
}

Все работает отлично. Но проблема в том, что каждый раз получать сервис через контекст, как это указано в коде (PersonService ps = autowireCapableBeanFactory.createBean(PersonService.class);), мягко говоря не удобно.

Answer 1

Укажите в аннтоции @ComponentScan базовый пакет для сканирования @ComponentScan("com.company"). Возможно Spring просто не видит ваши классы.

Answer 2

Аннотация @Autowired работает только в бинах.

В main имеет смысл только инициализировать контекст и получать из него "корневой" бин. А всю остальную работу делать в этом бине и бинах в него внедрённых.

@Component
public class Application {
    @Autowired
    private PersonService personService;
    public void start() {
        for (Person p : personService.findAll()) {
            System.out.println(p);
        }        
    }
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        AutowireCapableBeanFactory autowireCapableBeanFactory = context.getAutowireCapableBeanFactory();
        Application app = autowireCapableBeanFactory.createBean(Application.class);
        app.start();
    }
}
READ ALSO
Не запускается скомпиленный jar IDEA

Не запускается скомпиленный jar IDEA

Пользуюсь IDEAПриложение Swing

185
Как создавать базу данных в указанной директории SQLite Android

Как создавать базу данных в указанной директории SQLite Android

Как создавать базу данных в указанной директории?

176
реализация Map java [требует правки]

реализация Map java [требует правки]

На базе существующих реализаций интерфейса Map, создать реализацию Map, которая будет гарантированно выдавать ключи в том же порядке, в котором...

234
ExpandableListView с меняющимися цветами

ExpandableListView с меняющимися цветами

Есть ExpandableListView и 2 цветаОно должно работать по такому принципу: должен быть родительский синий, потом дочерней красный, затем дочерний 2 синий,...

155