我可以通过ApplicationContext获取由Spring容器的Ioc创建的bean吗?

时间:2018-10-17 03:22:13

标签: java spring annotations autowired applicationcontext

现在我正在通过春季@Autowired获得由注释ApplicationContext定义的bean,我应该非法这样做吗?

@Autowired
IAppAppService  appAppService;
private void someMethod(){
     Object obj = applicationContext.getBean("appAppService");
}

我将得到一个org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'appAppService' is defined异常。如何手动检索此bean?

一个例子可能是:

@Service
@Path("/pipingMessage")
public class AppInfoSyncServiceRest {
    @Autowired
    private IAppAppService     appAppService;
    @Autowired
    private ApplicationContext  applicationContext;

    @Path("/handleChange")
    @GET
    public void retrieveInfo(){
      try {
        //this line will get that NoSuchBeanDefinitionException
        Object obj = applicationContext.getBean("appAppService");
        Method method = obj.getClass().getMethod("getByAppId",long.class);
        List<Object> list = (List<Object>)method.invoke(obj, new Object[] {id});
        .....
        } catch (BeansException e) {
            LOGGER.info("base",e);
        } catch (IllegalStateException e) {
            LOGGER.info("illegal",e);
        } catch (NoSuchMethodException e) {
            LOGGER.info("nosuchmethod",e);
        } catch (SecurityException e) {
            LOGGER.info("security",e);
        } catch (IllegalAccessException e) {
            LOGGER.info("illegalaccess",e);
        } catch (IllegalArgumentException e) {
            LOGGER.info("illegalargument",e);
        } catch (InvocationTargetException e) {
            LOGGER.info("invocation",e);
        }
    }
}

public interface IAppAppService {
    public  List<AppAppEntity> getByAppid(long appid);
}

@Service
@Transactional
public class AppAppServiceImpl implements IAppAppService {
    @Override
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<AppAppEntity> getByAppid(long appid) {
        return appAppEntityDAO.getByAppid(appid);
    }
}

@Repository
public class AppAppEntityDAO extends HibernateDao<AppAppEntity, Long> {
     public List<AppAppEntity> getByAppid(long appid) {
         String hql = "from AppAppEntity  where targetAppid =?";
         return this.find(hql, appid);
     }
}

@Entity
@Table(name = "table_name_xxx")
public class AppAppEntity implements java.io.Serializable {
    private Long targetAppid;

    @Column(name = "source_appid", nullable = false)
    public Long getSourceAppid() {
        return this.sourceAppid;
    }

    public void setSourceAppid(Long sourceAppid) {
        this.sourceAppid = sourceAppid;
    }
}

1 个答案:

答案 0 :(得分:-1)

Spring中默认的自动连线模式是按类型自动连线。如果没有自动更改自动接线模式,则在这种情况下

@Autowired
private IAppAppService appAppService;

如果实例在应用程序上下文中可用,则容器将注入IAppAppService类型的实例。

ApplicationContext中的 getBean 方法按名称查找bean。所以在这种情况下

Object obj = applicationContext.getBean("appAppService");

即使上下文中存在IAppAppService类型的实例,也会抛出异常,因为该实例名称不是 appAppService 。为了能够使用 appAppService 名称检索实例,IAppAppService的具体实现需要使用名称​​ appAppService 。可以通过将“ appAppService”传递给类上的@Service注释来设置名称

@Service("appAppService")
public class AppAppService implements IAppAppService {
...
}

归纳起来,在描述的这段代码中,因为从方法中抛出了 NoSuchBeanDefinitionException ,这意味着应用程序启动了,这意味着自动连线模式是默认模式(通过类型),并且上下文中存在 IAppAppService 类型的实例。如果在上下文中不存在类型为 IAppAppService 的实例,则该应用程序将无法启动(使用@Autowired注释且没有任何参数的字段是必需的,并且如果无法填充这些字段,则该应用程序将不会启动)。另一方面,当通过名称(使用 getBean 方法)查找bean时,将引发异常,因为即使上下文中存在类型为 IAppAppService 的实例,该实例也不存在名称为 appAppService