class 使用 ApplicationContext 初始化 bean 时抛出异常

class cast exception while initializing bean using ApplicationContext

我需要你的帮助来解决有关 spring bean 初始化的问题。以下是问题的详细信息:

dao 接口

  package com.dao;

  import com.entity.Employee;

  public interface IEmployeeDao {

       Employee create(final Employee aEmployee);
       Employee fetchEmployeeById(final Integer aEmployeeId);
  }

dao impl class

  package com.dao.impl;

  import javax.persistence.EntityManager;

  import com.dao.IEmployeeDao;
  import com.entity.Employee;

  public class EmployeeDao implements IEmployeeDao {

      private EntityManager em;

      @Override
      public Employee create(Employee aEmployee) {
           return this.em.merge(aEmployee);
      }

      @Override
      public Employee fetchEmployeeById(Integer aEmployeeId) {
         return this.em.find(Employee.class, aEmployeeId);
      }
  }

主要 class :

  package com.client;

  import java.sql.SQLException;

  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  import org.springframework.context.ApplicationContext;
  import org.springframework.context.support.ClassPathXmlApplicationContext;

  import com.dao.impl.EmployeeDao;

  public class Client {
       private static final Logger LOGGER = LogManager.getLogger(Client.class);

       public static void main(String[] args) throws ClassNotFoundException, 
          SQLException {
       ApplicationContext applicationContext = new 
       ClassPathXmlApplicationContext(new String[] {"applicationcontext.xml"});
       LOGGER.info("client invoked");
       EmployeeDao employeeDao =  
         (EmployeeDao)applicationContext.getBean("employeeDao");    
       //....some code below
     }
   }

我试图获取 employeeDao bean 的代码的最后一行抛出以下异常:

  Exception in thread "main" java.lang.ClassCastException: 
  com.sun.proxy.$Proxy17 cannot be cast to 
  com.dao.impl.EmployeeDao
  at com.client.Client.main(Client.java:26)

正如我浏览的一些答案中所建议的那样,我将上面的行更改为转换为接口而不是其实现 class

    IEmployeeDao employeeDao =  
         (IEmployeeDao)applicationContext.getBean("employeeDao");

bean 无一例外地被注入,但现在实际的实现方法没有被调用,即现在当我像下面这样调用 EmployeedDao 的创建方法时

  employeeDao.create(new Employee());

未调用创建方法实现,即以下方法:

  @Override
  public Employee create(Employee aEmployee) {
       System.out.println("com.dao.impl.EmployeeDao.create(Employee) callled")
       return this.em.merge(aEmployee);
  }

我通过系统输出消息确认了它。

请告诉我我做错了什么或者可以做些什么来解决这个问题。我还在下面发布了 bean 配置文件和 maven depedencies。

applicationcontext.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd ">
    <import resource="aspects.xml"/>
    <bean id="employeeDao" class="com.dao.impl.EmployeeDao" />

    </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"
         xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">

         <bean id="logAspect" 
               class="com.logging.LoggingAspect" />

         <aop:config>

            <aop:aspect id="aspectLoggging" ref="logAspect">
            <aop:pointcut id="pointCutAround"
                 expression="execution(* 
         com.dao.IEmployeeDao.*(..))" />

         aop:around method="logAround" pointcut-ref="pointCutAround" />

     </aop:aspect>
     </aop:config>
     </beans>

maven 依赖项:

  <dependencies>
     <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>2.5.5</version>
     </dependency>
     <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>2.5.5</version>
     </dependency>
     <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.7.3</version>
     </dependency>
     <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.7.3</version>
     </dependency>      
     <dependency>
        <groupId>org.apache.derby</groupId>
        <artifactId>derby</artifactId>
        <version>10.13.1.1</version>
     </dependency>  
     <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-entitymanager</artifactId>
       <version>3.6.0.Final</version>
     </dependency>
     <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
     </dependency>
   </dependencies>

编辑:

LoggingAspect class:

  package com.logging;

  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  import org.aspectj.lang.JoinPoint;

  public class LoggingAspect {
       private static final Logger LOGGER = 
          LogManager.getLogger(LoggingAspect.class);
       public void logAround(JoinPoint aJoinPoint) {
               LOGGER.info("aspects logging enabled");
       }
 }

是的,您的看点有问题。它实际上并没有调用检测代码。试试这个:

public void logAround(ProceedingJoinPoint aJoinPoint) { // <<-- don't forget to change the type to ProceedingJoinPoint
  LOGGER.info("aspects logging enabled");
  aJoinPoint.proceed(); // this will continue to the instrumented code
}