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

前言:

除了mybatis 不是零配置,有些仍是有xml的配置文件在裏面的。css

註解是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值映射到當前參數中。html

 這裏我就不從一開始了。

pom.xml

項目結構:

先把上面的包,依次建立好,(webapp文件夾中的WEB-INF全部文件所有刪掉)java

咱們從 config (配置) 包開始吧。

RootConfig類 (相似於spring-root.xml配置文件同樣)git

複製代碼
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 )github

複製代碼
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類 (  配置 數據源  )web

複製代碼
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 類 (掃描 )spring

複製代碼
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文件)sql

複製代碼
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 啓動apache

運行效果:

那麼到這裏就開始咱們的 權限管理 了,激動。。。。。。

瞭解一下 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

相關文章
相關標籤/搜索