以静态方法使用Spring Data Repository

时间:2018-12-21 14:55:03

标签: java spring spring-repositories

我定义了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);
    }
}

我在诸如Francisco Speath的静态方法(如@Autowired and static method)中调用我的存储库

但是,如果我尝试调用方法并存储通知,则会收到此错误:

  

java.lang.NullPointerException:空

在此行:notificationRepo.save(notification);

我想这是因为在静态方法内部使用存储库,但是如果我从各处删除静态方法并尝试访问addNotification()方法,则会出现另一个错误:

  

不能从静态上下文中引用非静态方法

我在RestController中调用此addNotification()方法

@RequestMapping(method = RequestMethod.POST)
public Offer newOffer (@RequestBody Offer offer) {
    NotificationProcessing.addCampaignNotification(offer);
    return repo.save(offer);
}

那么在静态方法中使用存储库的解决方案是什么?

3 个答案:

答案 0 :(得分:1)

所引用的问题处理有关如何引用Spring从静态方法注入的实例字段的问题。
由于static修饰符无权访问实例字段,因此可能很有意义。
但这不是标准,它是遗留代码或库的解决方法,在这些方法中,听起来很复杂或无法将静态方法作为实例方法。

  

我想这是因为在静态方法内部使用存储库,   但是,如果我从任何地方都删除了静电并尝试访问   addNotification()方法存在另一个错误:

     

非静态方法不能从静态上下文中引用

你走错了路。
要使用Bean依赖项,您需要将其注入其他Bean中所需的位置。
您永远不会在bean中使用static修饰符来定义方法,而通过在类前面加上前缀来从另一个bean调用它。
Bean是实例。这些与类本身无关。

除了notificationRepo.save(notification);触发NullPointerException外,它还意味着一件事:您的类不是bean spring,因为如果无法解析notificationRepo依赖项,则Spring上下文将无法成功加载:< / p>

@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);
}

答案 1 :(得分:0)

创建对象实例时会调用

构造函数,因此用@Autowired标记构造函数并使用静态上下文中注入的实例看起来不合逻辑。如我所见,NotificationProcessing没有标记为@Component,所以我不确定它是否完全由容器处理。

我建议您从staticnotificationRepo中删除addNotification()修饰符,将类标记为@Component并从注入的实例中调用addNotification() NotificationProcessing

答案 2 :(得分:0)

我认为您应该将NotificationProcessing.addCampaignNotification(offer);更改为notificationProcessing.addCampaignNotification(offer);,并通过添加以下构造函数将notificationProcessing注入控制器:

@Autowired
public YourController(NotificationProcessing notificationProcessing) {
    this.notificationProcessing= notificationProcessing;
}