1、上篇中关于Jsr181HandlerMapping分析。
红箭头中指代的就是上篇中注入的三个参数。
2、其中ApplicationObjectSupport类实现了ApplicationContextAware接口方法:
public final void setApplicationContext(ApplicationContext context) throws BeansException {
if (context == null && !isContextRequired()) {
// Reset internal context state.
this.applicationContext = null;
this.messageSourceAccessor = null;
}
else if (this.applicationContext == null) {
// Initialize with passed-in context.
if (!requiredContextClass().isInstance(context)) {
throw new ApplicationContextException(
"Invalid application context: needs to be of type [" + requiredContextClass().getName() + "]");
}
this.applicationContext = context;
this.messageSourceAccessor = new MessageSourceAccessor(context);
initApplicationContext();
}
else {
// Ignore reinitialization if same context passed in.
if (this.applicationContext != context) {
throw new ApplicationContextException(
"Cannot reinitialize with different application context: current one is [" +
this.applicationContext + "], passed-in one is [" + context + "]");
}
}
}
以上红字加粗的代码非常重要。
3、在Jsr181HandlerMapping类中定义了该方法:
protected void initApplicationContext()
throws BeansException{
if (serviceFactory == null) {
serviceFactory = createServiceFactory();
}
ApplicationContext context = getApplicationContext();
while (true){
if (context == null) break;
processBeans(context, serviceFactory);
context = context.getParent();
}
}
其中红色字体createServiceFactory();创建了AnnotationServiceFactory类的实例
红色字体processBeans(context, serviceFactory);如下代码:
private void processBeans(ApplicationContext beanFactory,
AnnotationServiceFactory serviceFactory){
String[] beanNames = beanFactory.getBeanDefinitionNames();
ConfigurableApplicationContext ctxt = (ConfigurableApplicationContext) beanFactory;
// Take any bean name or alias that has a web service annotation
for (int i = 0; i < beanNames.length; i++) {
BeanDefinition def = ctxt.getBeanFactory().getBeanDefinition(beanNames[i]);
if (!def.isSingleton() || def.isAbstract()) continue;
Class clazz;
Object bean;
try
{
clazz = getApplicationContext().getType(beanNames[i]);
bean = beanFactory.getBean(beanNames[i]);
try
{
clazz = SpringUtils.getUserTarget(bean).getClass();
}
catch (Exception e)
{
logger.error("Failed to get the User Target Class of bean " + beanNames[i], e);
}
}
catch (BeanIsAbstractException e)
{
// The bean is abstract, we won't be doing anything with it.
continue;
}
if (clazz != null &&
!Modifier.isAbstract(clazz.getModifiers()) &&
webAnnotations.hasWebServiceAnnotation(clazz))
{
Service endpoint = serviceFactory.create(clazz);
customizeService(bean, endpoint);
}
else
{
if (logger.isDebugEnabled())
{
logger.debug("Rejected bean '" + beanNames[i] + "' since it has no WebService annotation");
}
}
}
}
4、红色字体Service endpoint = serviceFactory.create(clazz); 是李永ServiceFactory创建Service的方法
紫色字体customizeService(bean, endpoint);是定制系统使用的WebService,其中的代码为:
protected void customizeService(Object bean, Service endpoint) {
if (logger.isInfoEnabled())
{
logger.info("Exposing service " + endpoint.getName() +
" to " + urlPrefix + endpoint.getSimpleName());
}
if( getInHandlers()!= null ){// 添加 InHandlers
endpoint.getInHandlers().addAll(getInHandlers());
}
if( getOutHandlers()!= null ){// 添加 OutHandlers
endpoint.getOutHandlers().addAll(getOutHandlers());
}
if( getFaultHandlers()!= null ){// 添加 FaultHandlers
endpoint.getFaultHandlers().addAll(getFaultHandlers());
}
//----- 将该 WebService 调用XFire的注册器注入进去
xFire.getServiceRegistry().register(endpoint);
endpoint.setInvoker(new BeanInvoker(bean));
Object controller = createController(endpoint.getName());
registerHandler(urlPrefix + endpoint.getSimpleName(), controller);
}