@Autowired NPE

 
 
 
Сообщения:164
Делаю CRUD приложение на Spring и Hibernate.
Есть сервис (пакет ru.vallball.calendar01.service):
@Service
@Transactional
public class EventServiceImpl implements EventService{

Есть контроллер (пакет ru.vallball.calendar01.controller), куда он инжектируется:
@Controller
@RequestMapping(value = { "/"})
public class HomeController {
	
	@Autowired
	EventService eventService;

И есть некоторый класс (пакет ru.vallball.calendar01.model)для непростых вычислений, который так же использует EventServiceImpl:
public class DayList {
	
	@Autowired
	EventService eventService;


Суть проблемы - в контроллере сервис доступен: [email protected]
А в DayList - нет - eventService = null
Понять не могу, в какую сторону уже смотреть?
 
 
Сообщения:348
Может добавить аннотацию @Component на классом DayList?
 
 
Сообщения:164
Пробовал - почему-то не помогло.
 
 
Сообщения:348
А в Component Scan пакет, в котором находится класс прописан?
 
 
Сообщения:9831
Покажи весь DayList
 
 
Сообщения:164
vps:
А в Component Scan пакет, в котором находится класс прописан?

У DayList прописывал ComponentScan - там был корневой пакет ru.vallball.calendar01
Вот как выглядит DayList:
package ru.vallball.calendar01.model;

import java.time.LocalDate;
import java.time.Month;
import java.time.Year;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;

import ru.vallball.calendar01.service.EventService;
import ru.vallball.calendar01.service.UserService;

@Component
public class DayList {
	
	@Autowired
	EventService eventService;
	
	@Autowired
	UserService userService;
	
	private Year year;
	
	public DayList(){ 
		this.year = Year.now();
		}

public Year getYear() {
	return year;
}

//Получить месяц по номеру
	public Month getMonthName(int i) {
		return year.atMonth(i).getMonth();
	}

//список месяцев
	public List<Month> listMonths() {
		List<Month> list = new ArrayList<>();
		for (int i=1;i<=12;i++) {
			list.add(this.getMonthName(i));
		}
		return list;
	}

//	Получить количество недель в месяце
	public int getWeeks(YearMonth yearMonth) {
		int daysOfMonths = yearMonth.lengthOfMonth();
		int day = yearMonth.atDay(1).getDayOfWeek().getValue()-1;
		if (((double)(day+daysOfMonths)/7) == 4) return 4;
		else if ((day+daysOfMonths)/7 < 5) return 5;
		else return 6;			
	}
	
	//Получить список всех дней в месяце
			public List<LocalDate> createList(YearMonth yearMonth) {
				List<LocalDate> list = new ArrayList<>();
				for (int i = 1; i <= yearMonth.lengthOfMonth(); i++) {
						list.add(yearMonth.atDay(i));
					}
				return list;
			}
			
	//Получить все события в месяце
	public List<Event> listEvents(List<LocalDate> list) {
		List<Event> listEvents = new ArrayList<>();
		
		return listEvents;
	}
	
	public List<Week> listWeeks(Month month,User user){
		YearMonth yearMonth= this.year.atMonth(month.getValue());
		List<Week> listWeek = new ArrayList<>();
		int weeks = getWeeks(yearMonth); //количество недель в месяце
		int beg = yearMonth.atDay(1).getDayOfWeek().getValue(); //номер дня в неделе, с которого начинается месяц
		List<LocalDate> list = createList(yearMonth); //список всех дней в месяце
		Week firstWeek = new Week();
		Iterator<LocalDate> iterator = list.iterator();
		System.out.println("eventService "+eventService);
		System.out.println("userService "+userService);
		System.out.println(eventService.findByDateAndUser(iterator.next(),user));	
		System.out.println("Ща начнем перебирать..."+user.getUsername()+" beg="+beg);
		
		switch (beg) {
		case 1:	firstWeek.setMon(eventService.findByDateAndUser(iterator.next(),user));
				iterator.remove();
		case 2:	System.out.println(iterator.next());
		System.out.println(eventService.findByDateAndUser(iterator.next(),user));	
				firstWeek.setTue(eventService.findByDateAndUser(iterator.next(),user));
				iterator.remove();
		case 3:	firstWeek.setWed(eventService.findByDateAndUser(iterator.next(),user));
				iterator.remove();
		case 4:	firstWeek.setThu(eventService.findByDateAndUser(iterator.next(),user));
				iterator.remove();
		case 5:	firstWeek.setFri(eventService.findByDateAndUser(iterator.next(),user));
				iterator.remove();
		case 6:	firstWeek.setSat(eventService.findByDateAndUser(iterator.next(),user));
				iterator.remove();
		case 7:	firstWeek.setSun(eventService.findByDateAndUser(iterator.next(),user));
				iterator.remove();
			}
		listWeek.add(firstWeek);
		
		for (int i=2;i<weeks;i++) {
			Week week = new Week();
				week.setMon(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				week.setTue(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				week.setWed(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				week.setThu(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				week.setFri(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				week.setSat(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				week.setSun(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();		
				listWeek.add(week);
		}
		
		int size = list.size();
		Week lastWeek = new Week();
		
		switch (size) {
		case 7:	lastWeek.setMon(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				lastWeek.setTue(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				lastWeek.setWed(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				lastWeek.setThu(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				lastWeek.setFri(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				lastWeek.setSat(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				lastWeek.setSun(eventService.findByDateAndUser(iterator.next(), user));
				iterator.remove();
				break;
		
		case 6:	lastWeek.setMon(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setTue(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setWed(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setThu(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setFri(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setSat(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
			break;
		
		case 5:	lastWeek.setMon(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setTue(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setWed(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setThu(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setFri(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		break;
		
		case 4:	lastWeek.setMon(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setTue(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setWed(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setThu(eventService.findByDateAndUser(iterator.next(), user));
			break;
		
		case 3:	lastWeek.setMon(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setTue(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setWed(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		break;
		
		case 2:	lastWeek.setMon(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		lastWeek.setTue(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
			break;
		
		case 1:	lastWeek.setMon(eventService.findByDateAndUser(iterator.next(), user));
		iterator.remove();
		break;
				}
		listWeek.add(lastWeek);
		return listWeek;

	}
}


Добавил в DayList:
@Component
@ComponentScan("ru.vallball.calendar01.service")
public class DayList {


Но всё равно:
eventService null
userService null
Изменен:19 апр 2019 05:57
 
 
Сообщения:348
А можно ещё файл конфигурации посмотреть?
 
 
Сообщения:164
А у меня конфигурация не файлом задается. А через класс:
package ru.vallball.calendar01.config;

import javax.servlet.Filter;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
	
	public static final String CHARACTER_ENCODING = "UTF-8";

	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class[] {HibernateConfig.class,WebSecurityConfig.class};
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class[] {WebMvcConfig.class};
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}

	@Override
    protected Filter[] getServletFilters() {
        final CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding(CHARACTER_ENCODING);
        encodingFilter.setForceEncoding(true);
        return new Filter[] { encodingFilter };
    }

}


Ваш текст
 
 
Сообщения:348
Не, не этот, а в котором идет конфигурация создания бинов приложения.
 
 
Сообщения:164
Возможно, у спринга это идет как-то под капотом?
Вот какие файлы есть у меня в папке config:
AppInitializer
HibernateConfig
SecurityWebApplicationInitializer
WebMvcConfig
WebSecurityConfig
 
 
Сообщения:348
Если я правильно понимаю, то создание бинов прописано в этих классах:
HibernateConfig, WebSecurityConfig и WebMvcConfig.
 
 
Сообщения:164
package ru.vallball.calendar01.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import ru.vallball.calendar01.model.Event;
import ru.vallball.calendar01.model.User;

@Configuration
@EnableTransactionManagement
@ComponentScans(value = { @ComponentScan("ru.vallball.calendar01")})
public class HibernateConfig {
	
	 @Autowired
	 private ApplicationContext context;
	 
	 @Bean
	    public LocalSessionFactoryBean getSessionFactory() {
	        LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
	        factoryBean.setConfigLocation(context.getResource("classpath:hibernate.cfg.xml"));
	        factoryBean.setAnnotatedClasses(Event.class,User.class);
	        return factoryBean;
	    }
	 
	    @Bean
	    public HibernateTransactionManager getTransactionManager() {
	        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
	        transactionManager.setSessionFactory(getSessionFactory().getObject());
	        return transactionManager;
	    }

}



package ru.vallball.calendar01.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "ru.vallball.calendar01"})
public class WebMvcConfig implements WebMvcConfigurer{
	
	@Autowired
	private ApplicationContext applicationContext;
	
	 @Bean
	   public SpringResourceTemplateResolver templateResolver() {
	      SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
	      templateResolver.setApplicationContext(this.applicationContext);
	      templateResolver.setPrefix("/WEB-INF/views/");
	      templateResolver.setSuffix(".html");
	      templateResolver.setCharacterEncoding("UTF-8");
	      return templateResolver;
	   }

	   /*
	    * STEP 2 - Create SpringTemplateEngine
	    * */
	   @Bean
	   public SpringTemplateEngine templateEngine() {
	      SpringTemplateEngine templateEngine = new SpringTemplateEngine();
	      templateEngine.setTemplateResolver(templateResolver());
	      templateEngine.setEnableSpringELCompiler(true);
	      return templateEngine;
	   }

	   /*
	    * STEP 3 - Register ThymeleafViewResolver
	    * */
	   @Bean
	   public ThymeleafViewResolver viewResolver(){
	       ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
	       viewResolver.setTemplateEngine(templateEngine());
	       viewResolver.setCharacterEncoding("UTF-8");
	       return viewResolver;
	   }


}


package ru.vallball.calendar01.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@ComponentScan("ru.vallball.calendar01")
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
	
	@Autowired
	private UserDetailsService userService;
	
	@Bean
	 public BCryptPasswordEncoder passwordEncoder() {
	    return new BCryptPasswordEncoder();
	  };
	  
	  @Override
	  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
	    auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
	  }
	  
	  protected void configure(HttpSecurity http) throws Exception {
		  http.authorizeRequests().anyRequest().hasRole("USER").
		  					and().formLogin();			  	  		
	  }

}


Я даже создал класс AppConfig

@ComponentScan("ru.vallball.calendar01")
@Configuration
public class AppConfig  {
   


Всё равно не работает.
 
 
Сообщения:164
Ну вот пока я не попробовал инжектить сервисы в DayList, всё нормально работало. Находились все бины. И продолжают находиться: [email protected]
Но почему-то именно в DayList это недоступно.
 
 
Сообщения:348
Может тогда попробовать убрать аннотации @ComponentScan и создавать все компоненты через @Bean?

P/S: или выложите на github минимально необходимый не работающий пример. Может так получится понять, в чём проблема.
Изменен:19 апр 2019 16:45
 
 
Сообщения:164
https://github.com/vall-ball/calendar01/blob/master/calendar01.7z
Здесь выложил в формате 7z.
war-файл был больше 25 Мб. Пришлось удалить из него все библиотеки.

Нашёл вот что в интернете:
"Dependecy Injection requires a dependency injector, a tool that injects an instance of UserService into a UserBean. In your code you're already using this injected instance during instantiation of the bean: you call the injected service in the constructor.

If the dependency injector starts it's work after the bean is created, then the call to the service inside the constructor will raise a NullPointerException (because service is still null at that time). It's worth checking that by trying to catch NPEs in the UserBean constructor for a moment. If you catch one - voilà - the dependency injector starts runnning after the bean has been created and, as a consequence, we can't use injected services during class instantiation (= in the constructor)"

То есть мой DayList возникает раньше, чем запустится инжектировщик бинов.
Сделал для DayList конструктор с параметрами:
public DayList(EventService eventService, UserService userService) {
		System.out.println("Конструктор Daylist");
		this.eventService = eventService;
		this.userService = userService;
		this.year = Year.now();
	}

Теперь сервисы не null.
И всё же странно, почему инжектировщик не поспевает за созданием DayList?
Изменен:22 апр 2019 06:20
 
Модераторы:wedens
Сейчас эту тему просматривают:Нет