使用IDEA搭建一个Spring + AOP (权限管理 ) + Spring MVC + Mybatis的Web项目 (零配置文件)

前言:

除了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

项目结构:

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

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

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 包 里面的类

复制代码
 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包中的接口

复制代码
 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包中的类

复制代码
 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 目录

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 启动

运行效果:

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

了解一下 AspectJ ? 地址:https://www.cnblogs.com/nongzihong/p/10190866.html

先创建一个包 aspect ( 切面 )

UserPowerAdvice 类 (切面类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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 包

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

 

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

 源码下载地址:https://github.com/nongzihong/Hello_wrold

posted @ 2018-12-28 15:18  随★风  阅读(565)  评论(0编辑  收藏  举报