1. Situation description
Using springboot2 multi-threading, thread classes cannot automatically inject needed beans. Solution ideas are made to obtain needed beans through tool classes.
as follows
package ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; /** * Author:ZhuShangJin * Date:2018/6/26 */ public class CdrHandler implements Runnable { public Cdr cdr; //Cannot be injected automatically public RedissonClient redissonClient; //Cannot be injected automatically public UserService userService; //Cannot be injected automatically public CallRecordService callRecordService; public CdrHandler() { //Inject the required bean when new = (); = (); = (); } public RedissonClient getRedissonClient() { return redissonClient; } public void setRedissonClient(RedissonClient redissonClient) { = redissonClient; } public Cdr getCdr() { return cdr; } public void setCdr(Cdr cdr) { = cdr; } public UserService getUserService() { return userService; } public void setUserService(UserService userService) { = userService; } public CallRecordService getCallRecordService() { return callRecordService; } public void setCallRecordService(CallRecordService callRecordService) { = callRecordService; } @Override public void run() { if (().getOuter() != null) { saveOuterCdr(); } else if (().getVisitor() != null) { saveVistorCdr(); } } private void saveOuterCdr() { // Outbound call ends CallCdr callCdr = null; RBucket<CallCdr> bucket = (RedisKeyPrefix.CALL_OUTER_CDR + ().getOuter().getId() + "_" + ()); callCdr = (); (RedisKeyPrefix.CALL_OUTER_CDR + ().getOuter().getId() + "_" + ()); (); (new Date()); ((().getDuration())); (().getTrunkNumber()); (new Date()); (().getRecording()); if (() == null){ (()); }else { long time = ().getTime() - ()*1000; (new Date(time)); } //todo Save to database User user = (new EntityWrapper<User>().eq("extension", () + "")); (()); (()); (()); (()); (new Date()); PhoneModel phoneModel = (()); if (phoneModel != null) { (()); (()); } (() + "" + ()); (callCdr); CallRecord callRecord = callCdr; boolean result = (callRecord); if (result) { (); } } private void saveVistorCdr() { CallCdr callCdr = null; RBucket<CallCdr> bucket = (RedisKeyPrefix.CALL_VISITOR_CDR + ().getVisitor().getId() + "_" + ()); callCdr = (); (RedisKeyPrefix.CALL_VISITOR_CDR + ().getVisitor().getId() + "_" + ()); (().getRecording()); PhoneModel phoneModel = (()); if (phoneModel != null) { (()); (()); } (() + "" + ()); (()); //Incoming call End of call External phone Call incoming Tonghu record of access to extension if ((, ().getType()) && ().getCdpn().length() == 5) { ((().getCdpn())); User user = (new EntityWrapper<User>().eq("extension", () + "")); (()); (()); (()); if ((, ())) { if ((().getRecording())) { // When the user missed an incoming call in the seat, no recording was performed. int ringLength = (int) ((new Date().getTime() - ().getTime()) / 1000); (ringLength); (0); } else { //Special situation: The seat will be hung up immediately after answering the call ((().getDuration())); (-1); (); } } else { //Normal situation ((().getDuration())); } } else if ((, ().getType()) && ().getCdpn().length() != 5) { //Customer service did not receive it (0); ("Not received"); (().getCdpn()); ("Not received"); (0); int ringLength = (int) ((new Date().getTime() - ().getTime())/1000); (ringLength); } (new Date()); (new Date()); (callCdr); if ((, ().getType()) && ().getCdpn().length() == 5 && (, ()) && (())) { }else if((,())){ }else { CallRecord callRecord = callCdr; boolean result = (callRecord); if (result) { (); } } } }
2. Tools for obtaining beans
package ; import ; import ; import ; import ; /** * Author:ZhuShangJin * Date:2018/7/3 */ @Component public class ApplicationContextProvider implements ApplicationContextAware { /** * Context object instance */ private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { = applicationContext; } /** * Get applicationContext * * @return */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * Get Bean by name. * * @param name * @return */ public static Object getBean(String name) { return getApplicationContext().getBean(name); } /** * Get Bean via class. * * @param clazz * @param <T> * @return */ public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } /** * Return the specified bean by name and Clazz * * @param name * @param clazz * @param <T> * @return */ public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }
3. Use the getBean method of the tool class to getBean
Supplementary knowledge:About Spring/SpringBoot's solution to inject Service in static tool class
Preface Today, the blogger will share with you: The solution to inject Service into static tool classes by Spring/SpringBoot! If you don’t like it, please feel free to discuss it if you have any objections!
Recently, I have encountered the need to inject Service into the tool class. Since methods in the tool class are generally static, the property must also be static (Service). However, because Spring/SpringBoot cannot support injection of static properties (null pointer exceptions will be reported). The main reason is that Spring's dependency injection actually depends on the Set method for injecting values, Spring is based on object-level dependency injection, and static properties/static variables actually belong to the class.
Solution:
Add @Component to the current tool class to make it a bean object
Declare a static property (plus annotation @Autowired), a non-static property.
Declare a method that returns void and cannot throw an exception, where a non-static property is assigned to a static property. Add annotation @PostConstruct to this method
This injects the service value into it. The sample code is as follows:
/** * *@Description: Solution about Spring/SpringBoot Injecting Service in Static Tool Class *@ClassName: *@author ChenYongJia *@Date June 26, 2019 at 21:20 pm *@Email chen87647213@ */ @Component public class XXUtils { @Autowired private SpecialLogSevice sevice; private static SpecialLogSevice specialLogSevice; @PostConstruct public void init() { specialLogSevice = sevice; } //The following content is omitted, you need to call specialLogSevice to handle the call }
In the above code, @PostConstruct is one of two new annotations that affect the servlet declaration cycle after the Java EE5 specification, and the other is @PreConstruct. Both of these can be used to modify a non-static method with a return value of void, and the method cannot throw exceptions.
The method modified by @PostConstruct annotation will run when the server loads the servlet and will only be called once by the server, similar to the init method in the servlet. The method modified by this annotation will be executed after the constructor is executed and before the init method is executed. Spring allows developers to use it in the accepted bean. When the IOC container is instantiated to manage the current bean, the method modified by the annotation will be executed to complete some initialization work.
The method modified by the PreConstruct annotation will run when the server uninstalls the Servlet, similar to the destroy method in the Servlet. The method modified by this annotation will be executed after the destroy method is executed and before the Servlet is completely uninstalled.
To this end: About Spring/SpringBoot's solution to inject Service into static tool classes! The sharing is over, go and try it! I hope everyone supports me!