2011-11-02 3 views
3

У меня есть служба, которая должна вызывать класс runnable.Как вы используете Runnable с использованием Spring Framework?

Вот строки кода, которые используются в моем сервисе.

@Autowired 
private LinkBrc2MemberProfile brcTask;     

// Background Task. 
SimpleAsyncTaskExecutor sate = new SimpleAsyncTaskExecutor(); 
sate.createThread(new LinkBrc2MemberProfile(user)); 

Вот мой Runnable класс

@Service 
public class LinkBrc2MemberProfile implements Runnable { 

    private final Logger log = LoggerFactory.getLogger(LinkBrc2MemberProfile.class); 

    @Autowired 
    private LoyaltyDao dao; 

    private Member member; 

    public LinkBrc2MemberProfile() { 
     super(); 
    } 

    public LinkBrc2MemberProfile(Member member) { 
     this.member = member; 
    } 

    public void run() { 
     log.debug("*** Member User Name: " + member.getString("USER_NAME")); 
     String emailAddress = member.getString("USER_NAME"); 
     Map<String, Object> map = dao.findBrcByEmailAddress(emailAddress); 
     log.debug("=========================================================="); 

     if(! map.isEmpty()) { 
      try { 
       //a.CUSTOMER_ID, a.EMAIL_ADDRESS, b.card_no 
       String customerId = (String) map.get("CUSTOMER_ID"); 
       String brcCardNumber = (String) map.get("CARD_NO"); 

       log.debug("\ncustomerId: " + customerId + " brcCardNumber: " + brcCardNumber); 
       if(!brcCardNumber.equals("")) { 
        // Add the Be Rewarded Card. 
        HashMap<String, String> userAttributes = new HashMap<String, String>(); 
        String brcNumber = member.getString("BREWARDED_CARD_NO"); 
        if (brcNumber.equals("")) { 
         userAttributes.put("BREWARDED_CARD_NO", brcCardNumber); 
         try { 
          member.putAll(userAttributes); 
         } catch (Exception e) { 
          String errorMessage = "Unable to save user's BRC information due to: " + e.getMessage(); 
          log.error("{}", errorMessage); 
         } 
        } 
       } 
      } catch (Exception e) { 
       log.error(e.getMessage()); 
       e.printStackTrace(); 
      } 
     } 
    } 

Я не вижу каких-либо ошибок в журнале, но в то же время он, кажется, не вызывая Runnable класс. Я где-то пропускаю аннотацию? Есть ли хорошие примеры, на которые вы можете указать мне, только те, которые я нашел, используют файлы XML для настройки класса runnable. Я хотел бы использовать аннотации. Заранее спасибо.

Я обновил свою услугу, чтобы сделать следующее.

Пожалуйста, помогите, мой DAO является NULL, так это выглядит, как мой @Autowired в моем Runnable класса не проводка его.

Я добавил следующий компонент в мой файл боб-config.xml.

<bean id="brcType" class="com.ws.ocp.service.LinkBrc2MemberProfile" scope="prototype"/> 

Я удалил аннотацию @Autowired и добавил следующее к моему классу обслуживания.

ClassPathResource rsrc = new ClassPathResource("bean-config.xml"); 
XmlBeanFactory factory = new XmlBeanFactory(rsrc); 
LinkBrc2MemberProfile brcTask = (LinkBrc2MemberProfile) factory.getBean("brcType");     

SimpleAsyncTaskExecutor sate = new SimpleAsyncTaskExecutor();    
// Set Member attribute 
brcTask.setMember(user); 
// Executer 
sate.execute(brcTask); 

Почему мой dao все еще недействителен?

ответ

6

Runnable будет вызывать NullPointerException, так как вы его создаете самостоятельно (используя оператор new) вместо того, чтобы позволить Spring создать его. Это, очевидно, означает, что атрибут DAO с автоуведомлением не будет автообновлен, что приведет к NPE при вызове dao.findBrcByEmailAddress(...).

Вы должны получить экземпляр Runnable от фабрики компонентов (в качестве прототипа), установить его атрибут-член и затем отправить его исполнителю.

+0

Итак, если я правильно вас понимаю, «autowire» LinkBrc2MemberProfile добавляет setter для моего члена, а затем передает это в sate.createThread (brcTask); – Byron

+0

Да, но убедитесь, что он настроен как прототип, а не синглтон, так как он имеет состояние. –

+0

Спасибо @JB Nizet один последний вопрос, какова аннотация для прототипа? Я только что обновил свой пост, пожалуйста, сообщите, правильно ли это настроить Runnable в качестве прототипа? – Byron

1

Чтобы ответить на ваш вопрос о том, как правильно использовать Prototype-Bean, это мой любимый способ:

@Component 
abstract class MyBean { 
    /* Factory method that will be installed by Spring */ 
    @Lookup 
    protected abstract YourPrototypeBean createBean(); 

    void someCode() { 
     YourPrototypeBean bean = createBean(); 
    } 
} 

Поскольку это фабричный метод, вы можете создать столько экземпляров, как вам нравится.

+1

Обратите внимание, что ['@ Lookup'] (https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Lookup.html) работает с Spring 4.1. – naXa