无xml的SpringMVC


简单的嵌入式 Tomcat + 无Xml + SpringMVC 主要代码示例;不建议当作正式服务使用,虽然我已无BUG运行数月,但不确定会不会发生未知异常;文中大部分有注释;如有不懂百度即可,此文不做过多赘述;
版本(都是最新的):
Spring6+
Tomcat11+

主要配置 ApplicationMain(Tomcat的启动代码)

public class Webapp {

    static final Logger LOGGER = Logger.getLogger(Webapp.class.getName());

    static void testPort(int port) throws IOException {
        // 检测端口是否被占用
        ServerSocket socket = null;
        try {
            socket = new ServerSocket(port);
        } catch (IOException e) {
            System.err.println(port + " 端口已被占用");
            System.exit(0);
            return;
        } finally {
            socket.close();
        }
    }

    private static File createTempDir(String prefix) {
        try {
            File tempDir = Files.createTempDirectory(prefix + ".").toFile();
            tempDir.deleteOnExit();
            return tempDir;
        } catch (IOException var3) {
            throw new RuntimeException("Unable to create tempDir. java.io.tmpdir is set to " + System.getProperty("java.io.tmpdir"), var3);
        }
    }
    private static ClassLoader getDefaultClassLoader() {
        ClassLoader cl = null;
        try {
            cl = Thread.currentThread().getContextClassLoader();
        } catch (Throwable var3) {
            var3.printStackTrace();
        }
        return cl;
    }
    public static void main(String[] args) {
        int port = 8080;
        try {

            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("system.properties");
            Properties properties = new Properties();
            properties.load(inputStream);
            String p = properties.getProperty("port");
            if(StringUtil.isNotEmpty(p)) {
                port = Integer.parseInt(p);
            }

            LOGGER.warning("当前端口:"+port);

            if (args.length > 0) {
                port = Integer.parseInt(args[0]);
            }
            testPort(port);

            // Windows系统上运行必须要有webapps文件夹,不然启动不了,辣鸡!
            /*
            String osName = System.getProperties().getProperty("os.name");
            if (osName.toLowerCase().contains("windows")) {
                String path = Webapp.class.getResource("/").getPath() + "/webapps";
                File file = new File(path);
                if (!file.exists()) {
                    file.mkdir();
                }
            }
            */

            //Registry.disableRegistry();
            Tomcat tomcat = new Tomcat();
            //Tomcat工作目录
            //String tomcatBaseDir = createTempDir("tomcat[" + port + "]").getAbsolutePath();
            String tomcatBaseDir = getDefaultClassLoader().getResource("").getPath();
            tomcat.setBaseDir(tomcatBaseDir);
            LOGGER.info("Tomcat baseDir:" + tomcatBaseDir);

            //连接器配置
            //@see https://blog.csdn.net/chanrenyuan/article/details/46869475
            Connector connector = new Connector(Http11NioProtocol.class.getName());
            connector.setPort(port);
            connector.setURIEncoding("UTF-8");
            //connector.setProperty("address", InetAddress.getByName("localhost").getHostAddress());
            connector.setProperty("maxThreads", "200");
            connector.setProperty("maxConnections", "1000");//最大并发socket
            connector.setProperty("acceptCount", "10000");//请求访问队列数
            connector.setProperty("connectionTimeout", "30000");
            connector.setProperty("maxHeaderCount", "100");//最多支持的header数量
            connector.setProperty("maxParameterCount", "1000");//最多支持的参数数量
            //connector.setUseBodyEncodingForURI(false);//是否用contentType中的编码来解码
            //将此属性设置为true以使 Tomcat 使用接收请求的 IP 地址来确定将请求发送到的主机。
            //connector.setUseIPVHosts(false);
            connector.setProperty("server", "XingZhen");
            //connecto\
            // r.getProtocolHandler(); //自定义协议处理,如果需要
            connector.setProperty("bindOnInit", "false"); // 全部启动完成后才支持请求
            connector.setProperty("processorCache", "100"); //支持缓存对象数量,默认200
            connector.setProperty("socket.directBuffer", "false");//是否使用JDK的Byte缓冲

            /*
            //SSL
            //更改Scheme
            connector.setScheme("https");
            connector.setSecure(true);
            //跳转连接器
            Connector cc = new Connector(Http11NioProtocol.class.getName());
            cc.setScheme("http");
            cc.setPort(8080);
            cc.setRedirectPort(443);
            AbstractHttp11JsseProtocol<?> protocol = (AbstractHttp11JsseProtocol<?>) connector.getProtocolHandler();
            protocol.setSSLEnabled(true);
            protocol.setSslProtocol("TLS");
            protocol.setKeystoreFile("youle123456.p12");
            protocol.setKeystoreType("PKCS12");
            protocol.setKeystorePass("youle123456");
            protocol.setKeyAlias("tomcat");
            */

            tomcat.setConnector(connector);
            //tomcat.setHostname("192.168.31.186");
            tomcat.getHost().setAutoDeploy(false);

            String contextPath = "";
            Charset uriEncoding = StandardCharsets.UTF_8;
            //String contextDocBase = createTempDir("contextDocBase").getAbsolutePath();
            //String contextDocBase = Webapp.class.getClassLoader().getResource("").getPath();
            String contextDocBase = getDefaultClassLoader().getResource("").getPath();
            LOGGER.info("contextDocBase:" + contextDocBase);
            //tomcat.setAddDefaultWebXmlToWebapp(false);
            StandardContext context = (StandardContext) tomcat.addWebapp(contextPath, contextDocBase);
            //context.setParentClassLoader(getDefaultClassLoader());
            context.setRequestCharacterEncoding(uriEncoding.name());
            //不扫描 某些配置
            ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
            context.setReloadable(true);

            //TODO 开起文件上传支持 (HttpServletRequest.Part); Servlet3.0+支持 @MultipartConfig
            context.setAllowCasualMultipartParsing(true);

            //WebResourceRoot root = new StandardRoot(context);
            //root.addPreResources(new DirResourceSet(root, "/", contextDocBase, "/"));
            //context.setResources(root);


            ErrorPage ep = new ErrorPage();
            //ep.setErrorCode(500);
            ep.setLocation("/error");
            context.addErrorPage(ep);

            //tomcat.enableNaming();
            tomcat.start();
            tomcat.getServer().await();
        } catch (Exception e) {
            System.err.println("启动错误 Error:" + e.getMessage());
            System.err.println("命令启动时第一个参数为端口号(默认端口" + port + ")");
            e.printStackTrace();
        }
    }

}

主要配置 WebApplicationInitializer

public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);

        //druid链接池的监控配置
        ServletRegistration.Dynamic ctx = servletContext.addServlet("DruidServlet", StatViewServlet.class);
        ctx.setInitParameter("loginUsername", "admin");
        ctx.setInitParameter("loginPassword", "123456");
        ctx.addMapping("/druid/*");
    }

    // 返回Spring应用根容器中定义的beans,对应ContextLoaderListener,是Spring根容器
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{ RootConfig.class };
    }

    // 返回Spring MVC应用容器中定义的beans,对应DispatcherServlet中加载的bean
    // Spring MVC容器是根容器的子容器,子容器可以看到根容器中定义的beans,反之不行
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{ ServletConfig.class }; //StatViewServlet.class
    }

    // 指定映射拦截URL
    protected String[] getServletMappings() {
        return new String[]{ "/" };
    }

    // 修改 通过重写此方法修改DispatcherServlet的名称,对应<servlet-name></servlet-name>标签
    @Override
    protected String getServletName() {
        return super.getServletName();
    }

    //@Override
    //protected Filter[] getServletFilters() {
    //    return new Filter[]{new WebStatFilter()};
    //}

}

主要配置 RootConfig

@Configuration
//@ImportResource(locations = "classpath:config/app.xml")
@ComponentScan({"config", "service"}) //扫描的包路径
@PropertySource({"classpath:system.properties"})
@EnableTransactionManagement
public class RootConfig {
    private final Logger logger = LoggerFactory.getLogger(RootConfig.class);

    @Bean
    public ApplicationContextAware applicationContextAware(ApplicationContext ctx) {
        return args -> {
            System.err.println("beans:");
            String[] beanNames = ctx.getBeanDefinitionNames();
            //Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                System.err.println("---> " + beanName);
            }
            logger.warn("Bean Count: {}", ctx.getBeanDefinitionCount());
            logger.warn("==========- WEB服务启动完成 -==========");
        };
    }

}

主要配置 ServletConfig

@Configuration
@EnableWebMvc //@EnableWebMvc 同等 WebMvcConfigurationSupport
@ComponentScan("controller") //Controller控制器的包路径
public class ServletConfig {}

pom.xml:Spring,Tomcat

<!-- 此处用的版本: -->
<spring.version>6.1.8</spring.version>
<tomcat>11.0.0-M20</tomcat>

<dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>${spring.version}</version>
 </dependency>
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-aspects</artifactId>
     <version>${spring.version}</version>
 </dependency>
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
     <version>${spring.version}</version>
 </dependency>
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context-support</artifactId>
     <version>${spring.version}</version>
 </dependency>
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
     <version>${spring.version}</version>
 </dependency>
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-websocket</artifactId>
     <version>${spring.version}</version>
 </dependency>

<!--Tomcat-->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>${tomcat}</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-websocket</artifactId>
    <version>${tomcat}</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <version>${tomcat}</version>
</dependency>
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行真爸爸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值