Я определил 2 класса.
AndroidPush.java
public class AndroidPush {
private static String SERVER_KEY = "XXXXX";
private static String DEVICE_TOKEN = "XXXXX";
public static void main(String[] args) throws Exception {
String title = args[0];
String message = args[1];
sendPushNotification(title, message);
}
private static void sendPushNotification(String title, String message) throws Exception {
String pushMessage = "{\"data\":{\"title\":\"" +
title +
"\",\"message\":\"" +
message +
"\"},\"to\":\"" +
DEVICE_TOKEN +
"\"}";
URL url = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "key = " + SERVER_KEY);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
OutputStream outputStream = conn.getOutputStream();
outputStream.write(pushMessage.getBytes());
}
}
И
NotificationProcessing.java
public class NotificationProcessing {
private static NotificationRepo notificationRepo;
@Autowired
public NotificationProcessing(NotificationRepo notificationRepo) {
NotificationProcessing.notificationRepo = notificationRepo;
}
public static void addNotification(Offer offer) throws Exception {
Notification notification = new Notification();
notification.setId(null);
notification.setMessage("There is new offer: " + offer.getTitle());
notification.setLink("/offers/" + offer.getId());
notificationRepo.save(notification);
String[] arguments = new String[] {"New Offer", notification.getMessage()};
AndroidPush.main(arguments);
}
}
Я вызываю свой репозиторий внутри статического метода, например Франсиско Спит, ответившего на этот вопрос @Autowired и статический метод
Но затем, если я попытаюсь вызвать свой метод и сохранить уведомление, я получаю эту ошибку:
java.lang.NullPointerException: null
в этой строке: notificationRepo.save(notification);
Я полагаю, это связано с тем, что я использую репозиторий внутри статического метода, но если я удалю статику отовсюду и попытаюсь получить доступ к методу addNotification (), появится еще одна ошибка:
non-static method cannot be referenced from a static context
Я вызываю этот метод addNotification () внутри своего RestController
@RequestMapping(method = RequestMethod.POST)
public Offer newOffer (@RequestBody Offer offer) {
NotificationProcessing.addCampaignNotification(offer);
return repo.save(offer);
}
Итак, каково решение использования репозитория внутри статического метода?
честно говоря, я не хочу использовать этот метод как статический, но если я удалю статический, появится вторая ОШИБКА: «на нестатический метод нельзя ссылаться из статического контекста», и я вообще не могу запустить приложение. Поэтому, если есть какое-либо предложение избежать этой ошибки, когда я не использую статику, и объяснение, почему это происходит, было бы полезно




Конструктор вызывается, когда вы создаете экземпляр своего объекта, поэтому нелогично помечать конструктор с помощью @Autowired и использовать внедренные экземпляры из статического контекста. Как я вижу, NotificationProcessing не помечен как @Component, поэтому я не уверен, что он вообще обрабатывается контейнером.
Я бы рекомендовал вам удалить модификаторы static из notificationRepo и addNotification(), пометив класс как @Component и вызвать addNotification() из внедренного экземпляра NotificationProcessing.
Указанный вопрос касается того, как ссылаться на поле экземпляра, введенное Spring из статического метода.
Поскольку модификаторы static не имеют доступа к полям экземпляра, это может иметь смысл.
Но это не стандарт, это обходной путь для устаревшего кода или библиотек, когда кажется сложным или невозможным сделать статический метод методом экземпляра.
I suppose this is because using repository inside of static ethod, but if I remove static from everywhere and try to access addNotification() method there is another error:
non-static method cannot be referenced from a static context
Вы ошиблись.
Чтобы использовать зависимости bean-компонентов, вам необходимо внедрить их там, где они вам нужны, в других bean-компонентах.
Вы никогда не будете определять методы с модификатором static в компоненте и вызывать его из другого компонента, добавляя префикс класса.
Бобы - это экземпляры. Они не относятся к самому классу.
Кроме того, если notificationRepo.save(notification); запускает исключение NullPointerException, это означает одно: ваш класс не является bean-пружиной, потому что здесь контекст Spring не будет успешно загружен, если зависимость notificationRepo не может быть разрешена:
@Autowired
public NotificationProcessing(NotificationRepo notificationRepo) {
NotificationProcessing.notificationRepo = notificationRepo;
}
Короче говоря, аннотируйте свой класс, чтобы он стал Spring Bean, и удалите все эти статические модификаторы:
@Component
public class NotificationProcessing {
...
}
И введите это в контроллер:
private NotificationProcessing notificationProcessing;
public MyController(NotificationProcessing notificationProcessing){
this.notificationProcessing = notificationProcessing;
}
@RequestMapping(method = RequestMethod.POST)
public Offer newOffer (@RequestBody Offer offer) {
notificationProcessing.addCampaignNotification(offer);
return repo.save(offer);
}
Я думаю, вам следует изменить NotificationProcessing.addCampaignNotification(offer); на notificationProcessing.addCampaignNotification(offer); и вставить notificationProcessing в свой контроллер, добавив следующий конструктор:
@Autowired
public YourController(NotificationProcessing notificationProcessing) {
this.notificationProcessing= notificationProcessing;
}
Почему вы хотите использовать
addNotificationкак статический метод?