现在我正在通过春季@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;
}
}
答案 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