在Aspects中自动装配时出错

时间:2015-09-11 11:19:07

标签: java spring-aop

我在Aspect中调用bean时遇到了一些错误,我也希望对方面类中bean的初始化有一些建议。

  1. 我试图在我的方面类[1]中调用bean [2],但最后我得到以下错误[4]。似乎@Autowired参数没有初始化bean。我的配置文件在[3]中。我做错了什么?

  2. 我希望在初始化期间调用bean一次。因此,即使多次调用map函数,bean也已初始化。 另一个解决方案是,我想(我不知道是否可能),当第一次调用切入点mapreduce时,将初始化bean。 这些请求可以吗?

  3. 谢谢,

    [1]我的方面类

    @Aspect
    @Configurable
    @Component
    public class MapReduceAspects {
      @Autowired
      MedusaDigests digests;
    
      @Before("execution(* map(..))")
      public void mymap(JoinPoint joinPoint) {
        System.out.println("My Map Execution: " + joinPoint.getArgs() + ":" + joinPoint.getTarget());
        Object[] obj = joinPoint.getArgs();
    
        if (obj.length > 0) {
            byte[] key = convertToBytes(obj[0]);
            byte[] value = convertToBytes(obj[1]);
    
            digests.updateDigest(key, value);
        }
    }
    
    @Before("execution(* reduce(..))")
    public void myreduce(JoinPoint joinPoint) { System.out.println("My Reduce Execution");
       Object[] obj = joinPoint.getArgs();
    
       if (obj.length > 0) {
           byte[] key = convertToBytes(obj[0]);
           byte[] value = convertToBytes(obj[1]);
    
           digests.updateDigest(key, value);
        }
      }
    }
    

    [1]我的方面

    @Component
    public class MedusaDigests {
        private final String MD5 = "MD5";
        private MessageDigest mda = null;
    
        public MedusaDigests() {
            try {
                mda = MessageDigest.getInstance(MD5);
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
               e.printStackTrace();
           }
        }
    
        public void updateDigest(byte[] key, byte[] value) {
          mda.update(key);
          mda.update(value);
        }
    }
    

    [3]我的beans-aspects.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    <!--<aop:include name="mapreduceAspect"/>-->
    <!--<aop:include name="jobClient"/>-->
    <!--</aop:aspectj-autoproxy>-->
    <!--<context:load-time-weaver/>-->
    <context:component-scan base-package="org.apache.hadoop.mapred"/>
    
    <bean id="mapreduceAspect" class="org.apache.hadoop.mapred.aspects.MapReduceAspects" factory-method="aspectOf" autowire="byType" />
    <bean id="medusaDigests" class="org.apache.hadoop.mapred.MedusaDigests"/>
    

    [4]我得到的错误

    WARNING: job_local138234703_0001
    java.lang.Exception: java.lang.NullPointerException at org.apache.hadoop.mapred.LocalJobRunner$Job.runTasks(LocalJobRunner.java:462)
    at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:522)
    Caused by: java.lang.NullPointerException
    at org.apache.hadoop.mapred.aspects.MapReduceAspects.mymap(MapReduceAspects.java:50)
    at org.apache.hadoop.mapred.examples.DummyWordCount$Map.map(DummyWordCount.java:32)
    at org.apache.hadoop.mapred.examples.DummyWordCount$Map.map(DummyWordCount.java:1)
    at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:146)
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:787)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
    at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:243)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    

1 个答案:

答案 0 :(得分:0)

首先,您不需要在xml配置中声明bean并使用这样的注释:

<bean id="medusaDigests" class="org.apache.hadoop.mapred.MedusaDigests"/>
@Component
public class MedusaDigests {...}

您必须仅在一个地方声明bean,例如,您可以删除标记:

<bean id="mapreduceAspect" class="org.apache.hadoop.mapred.aspects.MapReduceAspects" factory-method="aspectOf" autowire="byType" />
<bean id="medusaDigests" class="org.apache.hadoop.mapred.MedusaDigests"/>

其次,标记

<context:component-scan base-package="org.apache.hadoop.mapred"/>

不会扫描Autowired注释,如果您还想扫描@Autowired注释,您可以选择以下两种变体之一:

在xml配置中声明

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

在xml配置中声明

<context:annotation-config/>