前言:

除了mybatis 不是零配置,有些还是有xml的配置文件在里面的。

注解是Spring的一个构建的一个重要手段,减少写配置文件,下面解释一下一些要用到的注解:

@Configuration 作用于类上面,声明当前类是一个配置类(相当于一个Spring的xml文件)
@ComponentScan(“xxx”) 作用于类上面,自动扫描xxx包名下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean
@Bean 作用与类和方法上,相当于Spring配置文件bean节点
@EnableWebMvc 作用于类,开启一些默认配置,如一些ViewResolver或者MessageConverter
@RequestMapping 作用于类、方法,配置URL和方法之间的映射
@RequestBody 作用于参数前,允许request的参数在request体中,而不是在直接链接在地址后面
@ResponseBody 作用于返回值、方法上,支持将返回值放在response体中,而不是返回一个页面。
@RequestParam 作用于参数前,将form的对应name值映射到当前参数中。

 这里我就不从一开始了。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.oukele.helloword</groupId>
    <artifactId>HelloWord2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>HelloWord2 Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>


    <dependencies>

        <!--spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>

        <!--spring mvc-->
       <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--MariaDB 数据库驱动  -->
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>2.3.0</version>
        </dependency>

        <!--c3p0 数据库连接池-->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>

        <!--servlet API-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <!-- AspectJ -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>

        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

项目结构:

idea 打开每次都spring 配置检查_spring

先把上面的包,依次创建好,(webapp文件夹中的WEB-INF所有文件全部删掉)

我们从 config (配置) 包开始吧。

idea 打开每次都spring 配置检查_spring_02

RootConfig类 (类似于spring-root.xml配置文件一样)

1 package com.oukele.config.spring;
 2 
 3 import org.springframework.context.annotation.ComponentScan;
 4 import org.springframework.context.annotation.Configuration;
 5 import org.springframework.context.annotation.Import;
 6 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 7 
 8 @Configuration//声明当前类 是一个 配置类
 9 @ComponentScan(basePackages = "com.oukele.dao")//扫描 dao包 使用spring 注解的接口
10 @Import({SpringDaoConfig.class,SpringServlet.class})//导入其他配置
11 public class RootConfig {
12 
13 }

SpringWebConfig类 (相当于 spring-web.xml )

package com.oukele.config.mvc;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration//声明当前类是配置类 类似于 spring-web.xml 文件
@EnableWebMvc// 若无此注解 WebMvcConfigurer 无效
@ComponentScan(basePackages = {"com.oukele.controller","com.oukele.aspect"})//扫描控制层 和切面 包
@EnableAspectJAutoProxy// 激活 切面 代理
public class SpringWebConfig implements WebMvcConfigurer {
    //注册静态资源,没注册的话,网站是访问不了的
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/");
    }

}

 

SpringDaoConfig类 (  配置 数据源  )

1 package com.oukele.config.spring;
 2 
 3 import com.mchange.v2.c3p0.ComboPooledDataSource;
 4 import org.mybatis.spring.SqlSessionFactoryBean;
 5 import org.mybatis.spring.mapper.MapperScannerConfigurer;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.context.EnvironmentAware;
 8 import org.springframework.context.annotation.Bean;
 9 import org.springframework.context.annotation.Configuration;
10 import org.springframework.context.annotation.PropertySource;
11 import org.springframework.core.env.Environment;
12 import org.springframework.core.io.ClassPathResource;
13 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
14 
15 import javax.sql.DataSource;
16 import java.beans.PropertyVetoException;
17 import java.io.IOException;
18 
19 @Configuration
20 @PropertySource(value = "classpath:jdbc.properties")//加载资源文件
21 public class SpringDaoConfig implements EnvironmentAware {//数据层
22 
23     @Autowired
24     private Environment env;
25 
26     @Override
27     public void setEnvironment(Environment environment) {
28         this.env = environment;
29     }
30 
31     //配置数据源
32     @Bean
33     public DataSource dataSource() throws PropertyVetoException {
34         ComboPooledDataSource dataSource = new ComboPooledDataSource();
35         dataSource.setDriverClass(env.getProperty("jdbc.driver"));
36         dataSource.setJdbcUrl(env.getProperty("jdbc.url"));
37         dataSource.setUser(env.getProperty("jdbc.user"));
38         dataSource.setPassword(env.getProperty("jdbc.password"));
39         return dataSource;
40     }
41     //配置 mybatis
42     @Bean
43     public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException, PropertyVetoException {
44         SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
45         PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
46         factoryBean.setTypeAliasesPackage("com.oukele.entity");//实体类
47         factoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));// 映射 sql文件
48         factoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));//mybatis配置
49         factoryBean.setDataSource(dataSource());
50         return factoryBean;
51     }
52     // 简化调用 将 dao 放置 容器中  使用:比如
53     //@Autowired
54     //xxxMapper xxmaper ;
55     //也可以在类上面 直接使用 @ComponentScan 扫描接口
56     @Bean
57     public MapperScannerConfigurer mapperScannerConfigurer() {
58         MapperScannerConfigurer configurer = new MapperScannerConfigurer();
59         configurer.setBasePackage("com.oukele.dao");//扫描接口
60         configurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
61         return configurer;
62     }
63    
64 }

SpringServlet 类 (扫描 )

1 package com.oukele.config.spring;
 2 
 3 import org.springframework.context.annotation.ComponentScan;
 4 import org.springframework.context.annotation.Configuration;
 5 
 6 @Configuration
 7 @ComponentScan(basePackages = "com.oukele.servlet")
 8 public class SpringServlet {//服务层
 9 
10 }

WebConfig 类 (类似于 web.xml文件)

1 package com.oukele.config.web;
 2 
 3 import com.oukele.config.mvc.SpringWebConfig;
 4 import com.oukele.config.spring.RootConfig;
 5 import org.springframework.web.filter.CharacterEncodingFilter;
 6 import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
 7 
 8 import javax.servlet.Filter;
 9 
10 public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
11 
12     @Override
13     protected Class<?>[] getRootConfigClasses() {// (spring容器) 父容器
14         return new Class[]{RootConfig.class};
15     }
16 
17     @Override
18     protected Class<?>[] getServletConfigClasses() {//  (spring mvc容器)  子容器
19         return new Class[]{SpringWebConfig.class};
20     }
21 
22     @Override
23     protected String[] getServletMappings() {//映射
24         return new String[]{"/"};
25     }
26 
27     //设置编码 这里设置好像没有用。。。。。 有解决方案请告诉我,谢谢
28     @Override
29     protected Filter[] getServletFilters() {
30         CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
31         characterEncodingFilter.setEncoding("UTF-8");
32         return new Filter[]{characterEncodingFilter};
33     }
34 }

 Controller 包 里面的类

idea 打开每次都spring 配置检查_bc_03

1 package com.oukele.controller;
 2 
 3 import com.oukele.entity.User;
 4 import com.oukele.servlet.UserServlet;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.web.bind.annotation.*;
 7 import org.springframework.web.context.WebApplicationContext;
 8 
 9 import javax.servlet.http.HttpSession;
10 import java.util.HashMap;
11 import java.util.Objects;
12 
13 @RestController
14 public class LoginController {
15 
16     @Autowired
17     private WebApplicationContext webApplicationContext;
18 
19     @Autowired
20     private UserServlet userServlet;
21 
22     @RequestMapping(path = "/login/{name}/{password}", method = RequestMethod.GET,produces = "application/json;charset=utf-8")
23     public String login(@PathVariable("name") String name, @PathVariable("password") String password, HttpSession session) {
24         User user = new User();
25         user.setUserName(name);
26         user.setPassword(password);
27         session.setAttribute("username",user);//存入session中
28         Boolean aBoolean = userServlet.checkUser(user);
29         
30         if(aBoolean){
31             return "{\"msg\":\"登入成功\"}";
32         }
33 
34         return "{\"msg\":\"登入失败\"}";
35     }
36 
37     @GetMapping(path = "/Ioc")
38     public HashMap<String, String[]> getAllInfo() {
39 
40         return new HashMap<String, String[]>() {{
41             put("子容器", webApplicationContext.getBeanDefinitionNames());
42             put("父容器", Objects.requireNonNull(webApplicationContext.getParent().getBeanDefinitionNames()));
43         }};
44 
45     }
46 
47 }

 dao包中的接口

idea 打开每次都spring 配置检查_xml_04

1 package com.oukele.dao;
 2 
 3 import com.oukele.entity.User;
 4 import org.apache.ibatis.annotations.Select;
 5 import org.springframework.stereotype.Repository;
 6 
 7 @Repository
 8 public interface UserMapper {
 9 
10     //使用xml配置文件
11     int check(User user);
12     //使用注解
13     @Select("select count(*) from user where userName = #{userName} and password = #{password}")
14     int check1(User user);
15 
16 }

entity包中的类

idea 打开每次都spring 配置检查_xml_05

1 package com.oukele.entity;
 2 
 3 public class User {
 4     private String userName;
 5     private String password;
 6 
 7     public String getUserName() {
 8         return userName;
 9     }
10 
11     public void setUserName(String userName) {
12         this.userName = userName;
13     }
14 
15     public String getPassword() {
16         return password;
17     }
18 
19     public void setPassword(String password) {
20         this.password = password;
21     }
22 
23     @Override
24     public String toString() {
25         return "User{" +
26                 "userName='" + userName + '\'' +
27                 ", password='" + password + '\'' +
28                 '}';
29     }
30 }

servlet包中的类

1 package com.oukele.servlet;
 2 
 3 import com.oukele.dao.UserMapper;
 4 import com.oukele.entity.User;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Service;
 7 
 8 @Service
 9 public class UserServlet {
10 
11     @Autowired
12     private UserMapper userMapper;
13 
14     public Boolean checkUser(User user){
15         //根据传进来的参数,去数据库查找用户
16         int result = userMapper.check(user);
17         //如果查回来的结果不为零,说明数据库中有该用户,让他登陆,否则不让他登陆
18         if( result > 0 ){
19             return true;
20         }
21         return false;
22     }
23 
24 }

 resources 目录

idea 打开每次都spring 配置检查_bc_06

jdbc.properties 资源文件

1 jdbc.driver=org.mariadb.jdbc.Driver
2 jdbc.url=jdbc:mariadb://localhost:3306/test
3 jdbc.user=oukele
4 jdbc.password=oukele

mybatis-config.xml 配置文件

1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
 3 <configuration>
 4     <settings>
 5         <!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
 6         <setting name="useGeneratedKeys" value="true"/>
 7         <!-- 使用列别名替换列名 默认:true -->
 8         <setting name="useColumnLabel" value="true"/>
 9         <!-- 开启驼峰命名转换:Table {create_time} -> Entity {createTime} -->
10         <setting name="mapUnderscoreToCamelCase" value="true"/>
11     </settings>
12 </configuration>

mapper文件中的 UserMapper.xml 配置文件

1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 <!-- 扫描 接口-->
 4 <mapper namespace="com.oukele.dao.UserMapper">
 5 
 6     <select id="check" parameterType="com.oukele.entity.User" resultType="java.lang.Integer">
 7         select count(*) from user where userName = #{userName} and password = #{password}
 8     </select>
 9 
10 </mapper>

 好,到这里我们启动了试一下效果了,(我现在的数据库没有数据库的)

配置Tomcat 启动

运行效果:

idea 打开每次都spring 配置检查_bc_07

那么到这里就开始我们的 权限管理 了,激动。。。。。。

了解一下 AspectJ ? 地址:

先创建一个包 aspect ( 切面 )

idea 打开每次都spring 配置检查_spring_08

UserPowerAdvice 类 (切面类)

package com.oukele.aspect;

import com.oukele.dao.UserMapper;
import com.oukele.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;

@Component//注入容器
@Aspect//声明这是一个 切面类
public class UserPowerAdvice {

    @Autowired
    HttpSession session;

    @Autowired
    UserMapper userMapper;

    //切点
    @Pointcut("execution(* com.oukele.controller.*.login(..))")
    public void power() {
    }

    ;

    //环绕通知
    @Around("power()")
    public Object seeStatus(ProceedingJoinPoint joinPoint) {
        try {

            // ......前环绕通知 --> 在原方法还没有执行前先执行

            Object o = joinPoint.proceed();//执行被代理的方法  //环绕通知 能覆盖原方法

            // .......后环绕通知 --> 在原方法执行后执行

            //从session中取出 存储的信息
            User user = (User) session.getAttribute("username");
            //作为 演示 这里的逻辑就随意一写哈
            //如果用户名不为空和密码不为空,去数据库查询,这里呢 我数据库只有用户名和密码
            //所以 我这里 如果 用户名为 oukele 则为管理管 否则都是普通用户
            if (!user.getUserName().isEmpty() && !user.getPassword().isEmpty()) {
                //去数据库中查询,结果大于 0 则存在用户 否则
                int result = userMapper.check1(user);
                if (result > 0) {
                    if (user.getUserName().equals("oukele")) {
                        return "{\"msg\":\"该用户 " + user.getUserName() + " 是 管理员\"}";
                    } else {
                        return "{\"msg\":\"该用户 " + user.getUserName() + " 不是 管理员\"}";
                    }
                } else {
                    return "{\"msg\":\"用户不存在。。\"}";
                }
            } else {
                return "{\"msg\":\"用户名或者密码为空。。\"}";
            }


        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return null;
    }

}

 在SpringWebConfig 类 加上 @EnableAspectJAutoProxy 注解 和 扫描 aspect 包

idea 打开每次都spring 配置检查_spring_09

运行效果(数据库没有数据的情况下):

 

idea 打开每次都spring 配置检查_spring_10

在有数据的情况下的效果:

idea 打开每次都spring 配置检查_spring_11

 源码下载地址: https://github.com/oukele/Spring-AOP-Spring-MVC-Mybatis-




除了mybatis 不是零配置,有些还是有xml的配置文件在里面的。

注解是Spring的一个构建的一个重要手段,减少写配置文件,下面解释一下一些要用到的注解:

@Configuration 作用于类上面,声明当前类是一个配置类(相当于一个Spring的xml文件)
@ComponentScan(“xxx”) 作用于类上面,自动扫描xxx包名下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean
@Bean 作用与类和方法上,相当于Spring配置文件bean节点
@EnableWebMvc 作用于类,开启一些默认配置,如一些ViewResolver或者MessageConverter
@RequestMapping 作用于类、方法,配置URL和方法之间的映射
@RequestBody 作用于参数前,允许request的参数在request体中,而不是在直接链接在地址后面
@ResponseBody 作用于返回值、方法上,支持将返回值放在response体中,而不是返回一个页面。
@RequestParam 作用于参数前,将form的对应name值映射到当前参数中。