spring整合velocity使用directive自定义标签类,引用service层实例无法注解注入问题

  1. 配置velocity自定标签。
  2. 调试时发现自定义标签类由spring依赖注入的实例service方法为null。
  3. 断点跟踪自定义标签继承类Directive的init方法。发现@Resource、@Autowired注入无效的原因是用户自定义标签类的实例由反射生成,不由spring容器创建。
                            org.apache.velocity.runtime.directive.Directive.init()
                            ->
                            org.apache.velocity.runtime.RuntimeInstance.init()
                            ->
                            org.apache.velocity.runtime.RuntimeInstance.initializeDirectives()
                            ->
                            loadDirective() 【自定义标签实例创建方法】
  4. 查看Directive.init(),断点入参RuntimeServices类,发现该类中有引用servlet容器的上下文,并可以用getApplicationAttribute()取出。
                            
                          重写自定义标签类中的init的方法,使用RuntimeServices类获取上下文容器。
           servletContent转换为->WebApplicationContex->并使用WebApplicationContext.get获取service实例方法并直接设置。
  5. 页面正常断点执行velocity自定义标签类的render方法时可以看到spring管理的实例时已注入。
                            
                             可在自定义标签类中重写init方法通过RunTimeServices获取spirng上下文获取service业务实例。
  6. 代码:
    import org.apache.velocity.context.InternalContextAdapter;
    import org.apache.velocity.exception.MethodInvocationException;
    import org.apache.velocity.exception.ParseErrorException;
    import org.apache.velocity.exception.ResourceNotFoundException;
    import org.apache.velocity.exception.TemplateInitException;
    import org.apache.velocity.runtime.RuntimeServices;
    import org.apache.velocity.runtime.directive.Directive;
    import org.apache.velocity.runtime.parser.node.Node;
    import org.springframework.web.context.WebApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;
    
    import javax.servlet.ServletContext;
    import java.io.IOException;
    import java.io.Writer;
    
     
    public class OrderSourceSelectDirective extends Directive {
    
        private  RuleFacadeService ruleFacadeService;//业务service
    
        @Override
        public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException {
            super.init(rs, context, node);
            ServletContext sc = (ServletContext) rs.getApplicationAttribute("javax.servlet.ServletContext");   //获取servlet上下文容器
            WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(sc);//获取spring上下文容器
            this.ruleFacadeService =  webApplicationContext.getBean(RuleFacadeService.class);  //从spring容器中取出service层实例,设值此反射创建的自定义标签类实例中
        }
    
        /**
         * 标签名
         */
        @Override
        public String getName() {
            return "orderSourceSelect";
        }
    
        /**
         * 标签类型
         * LINE: 不要#end结束符,
         * BLOCK:需要#end结束符
         */
        @Override
        public int getType() {
            return LINE;
        }
    
        /**
         * 标签输出内容
         */
        @Override
        public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException {
                    System.out.println(ruleFacadeService); //业务service
            return true;
        }
     
    }

     

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值