错误javax.servlet.ServletException: Servlet.init() for servlet com.hank.controller.UserLogin threw exc

错误javax.servlet.ServletException: Servlet.init() for servlet com.hank.controller.UserLogin threw exception的解决:

背景
在写Spring的时候init()方法脑热写出来的错误:
浏览器错误提示:
请添加图片描述
错误日志:
exception
javax.servlet.ServletException: Servlet.init() for servlet com.hank.controller.UserLogin threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
org.apache.coyote.AbstractProtocol A b s t r a c t C o n n e c t i o n H a n d l e r . p r o c e s s ( A b s t r a c t P r o t o c o l . j a v a : 637 ) o r g . a p a c h e . t o m c a t . u t i l . n e t . J I o E n d p o i n t AbstractConnectionHandler.process(AbstractProtocol.java:637) org.apache.tomcat.util.net.JIoEndpoint AbstractConnectionHandler.process(AbstractProtocol.java:637)org.apache.tomcat.util.net.JIoEndpointSocketProcessor.run(JIoEndpoint.java:318)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor W o r k e r . r u n ( T h r e a d P o o l E x e c u t o r . j a v a : 624 ) o r g . a p a c h e . t o m c a t . u t i l . t h r e a d s . T a s k T h r e a d Worker.run(ThreadPoolExecutor.java:624) org.apache.tomcat.util.threads.TaskThread Worker.run(ThreadPoolExecutor.java:624)org.apache.tomcat.util.threads.TaskThreadWrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
root cause

java.lang.ClassCastException: com.sun.proxy.Proxy127 cannot be cast to com.hank.service.Imp.UserServiceImp
com.hank.controller.UserLogin.init(UserLogin.java:29)
javax.servlet.GenericServlet.init(GenericServlet.java:158)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
org.apache.coyote.AbstractProtocolAbstractConnectionHandler.process(AbstractProtocol.java:637)
org.apache.tomcat.util.net.JIoEndpointSocketProcessor.run(JIoEndpoint.java:318)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)

错误代码:

  ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        userService = (UserServiceImp) ac.getBean("userservice");

错误原因分析:
因为aop底层默认是jdk动态代理的方式,而jdk动态代理是基于接口来实现的。生成的代理对象和真实对象的关系是实现一样的方法接口的平级关系。对于平级之间的强转这是很显然是错误的。
解决方案1
把生成的代理对象修改为强转为接口使用接口来获得代理对象的引用。

    private UserService userService;

    @Override
    public void init() throws ServletException {

//        ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());

        ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        userService = (UserService) ac.getBean("userservice");

解决方案2
开启aop的cglib动态代理方式:因为cglib动态代理是基于继承的方式来实现获得代理对象,因此获得代理对象和真实对象的关系是继承关系。因此可以强转。

开启步骤:

  1. 导入cglib的jar:
    . 在这里插入图片描述

    2.在s’pring的配置开启cglib动态代理

<!--    开启cjlib代理  基于继承-->
    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

总结aop底层两种代理方式:
1、jdk动态代理
原理:jdk动态代理基于接口的代理方式,动态生成的代理对象和真实对象实现同一接口。调用JDK官方的类文件获取动态生产的代理对象。


public class Myjdk implements InvocationHandler {//实现InvocationHandler接口 
     /**
     * 参数分析:
     *
     * Object proxy     代理对象
     * Method method    代理的方法对象
     * Object[] args    储存代理方法接受的实参的数组
     * */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("扩展前");
        Student student = new Student();
        student.show();
        System.out.println("扩展后");

        return null;
    }
}
//        jdk动态代理
        MyInter myInter = (MyInter) Proxy.newProxyInstance(
                test.class.getClassLoader(),//类加载器,加载动态生产的代理对象
                new Class[]{MyInter.class}, //动态生产的代理对象要实现的接口
                new Myjdk());//动态生成的 代理对象自动调用的扩展代码invocationHandler接口实现的

        myInter.show();//调用动态生成的代理对象的方法

2、cjlib动态代理
基于继承的方式来动态生成代理对象。需要导入cjlib 的jar,实现MethodInterceptor 接口
在这里插入图片描述

import net.sf.cglib.proxy.MethodInterceptor;

import java.lang.reflect.Method;

public class MyStudent implements MethodInterceptor {

    /**
     * 参数分析:
     *
     * Object o  代理对象
     * Method method 真实方法对象
     * Object[] objects 储存了代理方法接收的实参数组
     * net.sf.cglib.proxy.MethodProxy methodProxy 代理方法对象
     * */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, net.sf.cglib.proxy.MethodProxy methodProxy) throws Throwable {

        System.out.println("cglib代理前");

        methodProxy.invokeSuper(o,objects);//使用反射

        System.out.println("cglib代理后");

        return null;
    }
}

Cglib调用:


import com.aop6_cglib.cglib.MyStudent;
import com.aop6_cglib.pojo.Student;
import net.sf.cglib.proxy.Enhancer;

public class test {
    public static void main(String[] args) {
        //cglib代理===》继承

        Enhancer enhancer = new Enhancer();//创建cglib对象
        enhancer.setSuperclass(Student.class);//设置生成代理对象所要继承的对象
        enhancer.setCallback(new MyStudent());//设置生成的代理对象的代理方法所执行的代码

        Student o = (Student) enhancer.create();//生成代理对象

        o.show();
    }
}

博主温馨提示:
如果你想练习这个层实现,导包别导错了。
jdk上面案例代码的包路径:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

cglib上面案例代码的包路径:
import net.sf.cglib.proxy.MethodInterceptor;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;

现在因为一些缘故,导致几个月说的Java日笔记总结不能按时发布。但是以后博主我以后会找时间补上javase的笔记。如果大家觉得有帮助就关注一下博主吧。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值