IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 错误javax.servlet.ServletException: Servlet.init() for servlet com.hank.controller.UserLogin threw exc -> 正文阅读

[Java知识库]错误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的笔记。如果大家觉得有帮助就关注一下博主吧。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:25:07  更:2021-08-22 13:25:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 20:58:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码