Solon v3.5.2

内核支持的几种特殊 Bean

</> markdown

这些特殊 Bean 尽是用 "@Component" 注解:

接口说明
org.noear.solon.core.bean.LifecycleBean带有生命周期接口的 Bean
org.noear.solon.core.event.EventListener本地事件监听,会自动注册 EventBus
org.noear.solon.core.handle.Filter过滤器
org.noear.solon.core.route.RouterInterceptor路由拦截器
org.noear.solon.core.handle.ActionExecuteHandler动作执行处理器。//用于执行Mvc参数整体转换及执行处理
org.noear.solon.core.handle.ActionArgumentResolver动作参数分析器。//用于执行Mvc参数分析
org.noear.solon.core.handle.ReturnValueHandler返回值处理器。//用于特定Mvc返回类型处理
org.noear.solon.core.handle.Render渲染器。//用于响应数据渲染输出
org.noear.solon.core.convert.Converter转换器。//用于简单的配置转换与Mvc参数转换
org.noear.solon.core.convert.ConverterFactory转换器工厂
org.noear.solon.core.LoadBalance.Factory负载平衡工厂

示例1:

  • InitializingBean
import org.noear.solon.annotation.Component;
import org.noear.solon.core.bean.LifecycleBean;

//可以,通过组件顺序位控制 start 执行的优先级(一般,自动更好!)
@Component
public class DemoCom implements LifecycleBean{
    @Override
    public void start() throws Throwable{
        //开始。在容器扫描完成后执行。如果依赖了别的 LifecycleBean,会自动排序
    }
    
    @Override
    public void preStop() throws Throwable{
        //预停止。在容器预停止时执行
    }
    
    @Override
    public void stop() throws Throwable{
        //停止。在容器停止时执行
    }
}
  • EventListener
import org.noear.solon.annotation.Component;
import org.noear.solon.core.event.EventListener;

//监听本地事件 //可以,通过组件顺序位控制优先级
@Component(index = 0)
public class DemoEventListener implements EventListener<DemoEvent>{
    @Override
    public void onEvent(DemoEvent event) throws Throwable{
        
    }
}

//发布本地事件
EventBus.publish(new DemoEvent());

示例2:for web

  • Filter

对所有请求有效,包括:静态文件请求,动态路由请求

import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;

//可以,通过组件顺序位控制优先级
@Component(index = 0)
public class DemoFilter implements Filter{
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable{
        chain.doFilter(ctx);
    }
}
  • RouterInterceptor

对动态路由请求有效(即静态文件除外)

import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.route.PathRule;
import org.noear.solon.core.route.RouterInterceptor;
import org.noear.solon.core.route.RouterInterceptorChain;
import org.noear.solon.lang.Nullable;

//可以,通过组件顺序位控制优先级
@Component(index = 0)
public class DemoRouterInterceptor implements RouterInterceptor{
    @Override
    public PathRule pathPatterns() {
        //路径匹配规则(null 表示所有路径) 
        return null; 
    }
    
    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        //执行拦截
        chain.doIntercept(ctx, mainHandler);
    }
    
    @Override
    public Object postResult(Context ctx, @Nullable Object result) throws Throwable {
        //提交结果确认(可以做类型转换,翻译等...)
        return result;
    }
}
  • ActionArgumentResolver

对控制器方法的注入提供扩展支持,比如要增加一个注解 "@Session"(在此注解的参数,从 ctx.sessionState 里取)

import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.ActionArgumentResolver;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.util.LazyReference;
import org.noear.solon.core.wrap.MethodWrap;
import org.noear.solon.core.wrap.ParamWrap;

/**
 * <pre>{@code
 * @Controller
 * public class DemoController {
 *     @Mapping
 *     public void demo(@Session("user") user){
 *
 *     }
 * }
 * }</pre>
 * */
@Component
public class DemoActionArgumentResolver implements ActionArgumentResolver {
    @Override
    public boolean matched(Context ctx, ParamWrap pWrap) {
        return pWrap.getAnnotation(Session.class) != null;
    }

    @Override
    public Object resolveArgument(Context ctx, Object target, MethodWrap mWrap, ParamWrap pWrap, int pIndex, LazyReference bodyRef) throws Throwable {
        Session anno = pWrap.getAnnotation(Session.class);
        return ctx.session(anno.value());
    }
}


@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Session {
    String value() default "";
}
  • ReturnValueHandler

对所有控制器执行返回有效。框架的响应式 Mono、Flux,小推送 SSE 等返回的特殊类型,就是由这个机制实现的。

import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.ReturnValueHandler;

@Component
public class DemoReturnHandler implements ReturnValueHandler {
    @Override
    public boolean matched(Context ctx, Class<?> returnType) {
        //类型匹配规则(当匹配时,则由 returnHandle 接管返回处理。否则按默认的 MVC 机制处理)
        return false;
    }

    @Override
    public void returnHandle(Context ctx, Object returnValue) throws Throwable {
        //返回处理
    }
}
  • Render

对响应结果做渲染转换处理,并输出。

import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Controller;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Render;

//替换现有的 "@json" 渲染器(即接管 json 渲染处理)
@Component("@json")
public class JsonRender implements Render{

    @Override
    public void render(Object data, Context ctx) throws Throwable {
        ctx.output(JSON.toJson(data));
    }
}

//或者通过控制器基类,对继承它的控制器有效
public class ControllerBase implements Render{

    @Override
    public void render(Object data, Context ctx) throws Throwable {
        ctx.output(JSON.toJson(data));
    }
}

@Controller
public class DemoController extends ControllerBase{

}

特殊的渲染处理,可以通过客户端 header 指定(一般用于 rpc 开发)。比如:

import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Render;

@Component("@demo")
public class JsonRender implements Render{

    @Override
    public void render(Object data, Context ctx) throws Throwable {
        ctx.output(JSON.toJson(data));
    }
}

//HttpUtils.http("http://...").header("X-Serialization","@demo").body(...).post()
  • Converter 转换器

适用于简单的配置注入转换,及请求表单注入转换

import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.exception.ConvertException;

@Component
public class DemoConverter implements Converter<String, Demo> {
    @Override
    public Demo convert(String value) throws ConvertException {
        return Demo.parse(value);
    }
}

//应用示例(http://....?demo=1。 通过转换器把 1 转为 Demo 实体)
@Controller
public class DemoController {
    @Mapping("test")
    public void test(Demo demo){
    
    }
}