Spring,AspectJ:反序列化对象的注入

Spring, AspectJ: injection for deserialized objects

我需要将一些对象放入 ActiveMQ,然后反序列化它。该对象包含应在反序列化时初始化的瞬态字段。根据此文档 (http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-atconfigurable),它应该在 Spring 中自动工作,但事实并非如此。 CloudBean 在反序列化后始终为 null。

这是我的 类:

package core.utilities.handlers;

//imports...

@Component
@Configurable
public class InitialCopyHandler implements JobHandler  {
    private static final long serialVersionUID = 2617677940515776720L;
    private static Logger logger = Logger.getLogger(InitialCopyHandler.class);
    private String username;
    private String password;

    @Autowired private transient CloudBean cloudBean;

    public InitialCopyHandler() {
    }

    public InitialCopyHandler( String username, String password ) {
        this.username = username;
        this.password = password;
    }

    @Override
    public void handle() {
        try {
            logger.info("Copy from default to " + username);
            String webCloudDataDir = cloudBean.getWebCloudDataDir();
            Sardine defaultSardine = cloudBean.getDefaultSardine();
            InputStream is = defaultSardine.get(webCloudDataDir + FILE_COUNTRIES_LIST);
            cloudBean.getUserSardine(username,password).put(webCloudDataDir + FILE_COUNTRIES_LIST, is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

CloudBean.java:

package core.domain.cloud;

//imports...

@Component
public class CloudBean {
    protected Sardine defaultSardine;
    protected Sardine userSardine;
    protected String webCloudDataDir;
    protected String webCloud;
    protected static String defaultCar;
    protected static String defaultCarPassword;
    protected HttpHeaders headers;

    @Autowired private ConfigurationFactory configuration;

    public CloudBean() {
    }

 // init block
    @PostConstruct
    private void init() {
        webCloudDataDir = configuration.getConfigurationValue(DEFAULT_CLOUD_WEBDAV_LOCATION) + DIR_CLOUD_DATA;
        webCloud = configuration.getConfigurationValue(DEFAULT_CLOUD_LOCATION);
        defaultCar = configuration.getConfigurationValue(DEFAULT_CLOUD_ACCOUNT);
        defaultCarPassword = configuration.getConfigurationValue(DEFAULT_CLOUD_ACCOUNT_PASSWORD);
        defaultSardine = SardineFactory.begin(defaultCar, defaultCarPassword);
        defaultSardine.enableCompression();

        headers = HttpUtilities.initHeaders(defaultCar,defaultCarPassword);
    }

    /**
     * Initializes Sardine for the particular user
     * @param username
     * @param password
     * @return Sardine
     */
    public Sardine getUserSardine( String username, String password ) {
        userSardine = SardineFactory.begin(username,password);
        userSardine.enableCompression();
        return userSardine;
    }

    public Sardine getDefaultSardine() {
        return defaultSardine;
    }

    public String getWebCloudDataDir() {
        return webCloudDataDir;
    }
}

摘自Consumer.java(反序列化部分):

@Override
public void onMessage(Message message) {
    if( message instanceof ObjectMessage ) {
        ObjectMessage objectMessage = (ObjectMessage)message;
        try {
            JobHandler msg = (JobHandler)objectMessage.getObject();
            es.execute(new Runnable() {
                @Override
                public void run() {
                    msg.handle();
                }
            });
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

怎么了?

在你的代码中 Spring 只是没有参与反序列化,所以它不能注入任何依赖项。

在链接的 spring 文档中,pojo 是由 spring 工厂创建的。您不能使用该方法,因为您是通过反序列化创建实例的。

你能做什么:

在您的 Consumer class 中注入一个 bean 工厂:

@Autowired    
AutowireCapableBeanFactory beanFactory;

反序列化对象后自动装配:

 JobHandler msg = (JobHandler)objectMessage.getObject();
 beanFactory.autowireBean(msg);

就这些了。