完成shiro中常见的设计模式和subject原理

master
sunzhiqiang23 5 years ago
parent 3cf54ef4c2
commit 04540bb7b4

@ -20,6 +20,9 @@ import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* <p></p>
@ -42,7 +45,6 @@ public class LoginShiro {
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
session.setAttribute("key", "value");
String key = (String) session.getAttribute("key");
System.out.println("key 值:" + key);
@ -51,9 +53,21 @@ public class LoginShiro {
UsernamePasswordToken token = new UsernamePasswordToken("system", "system");
try {
currentUser.login(token);
new Thread(() -> {
System.out.println("登陆成功,登录用户"+SecurityUtils.getSubject().getPrincipals());
}).start();
// ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10,
// 10L, TimeUnit.MILLISECONDS,
// new LinkedBlockingQueue<Runnable>());
//
// for (int i = 0; i < 10; i++) {
// executor.execute(()->{
// System.out.println(SecurityUtils.getSubject().getPrincipals());
// });
// }
} catch (UnknownAccountException uae) {
log.info("无此用户,用户名: " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {

@ -0,0 +1,69 @@
package test.thread;
import org.apache.shiro.SecurityUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-11 22:40
*/
public class TestThreadLocal {
static ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
public static void main(String[] args) {
ThreadLocal<Map<Object, Object>> threadLocal = new InheritableThreadLocalMap<>();
for (int i = 0; i < 10; i++) {
Map<Object, Object> map = new HashMap<>();
map.put("key", i);
threadLocal.set(map);
executor.execute(()->{
System.out.println(threadLocal.get().get("key"));
});
}
}
public static void testInThreadLocal(){
ThreadLocal<Map<Object, Object>> threadLocal = new InheritableThreadLocalMap<>();
Map<Object, Object> map = new HashMap<>();
map.put("key", "value");
threadLocal.set(map);
new Thread(() -> {
System.out.println(threadLocal.get().get("key"));
}, "input thread name").start();
}
public static void testThreadLocal(){
ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("测试threadLocal");
new Thread(() -> {
System.out.println(threadLocal.get());
}, "input thread name").start();
}
private static final class InheritableThreadLocalMap<T extends Map<Object, Object>> extends InheritableThreadLocal<Map<Object, Object>> {
/**
* This implementation was added to address a
* <a href="http://jsecurity.markmail.org/search/?q=#query:+page:1+mid:xqi2yxurwmrpqrvj+state:results">
* user-reported issue</a>.
* @param parentValue the parent value, a HashMap as defined in the {@link #initialValue()} method.
* @return the HashMap to be used by any parent-spawned child threads (a clone of the parent HashMap).
*/
@SuppressWarnings({"unchecked"})
protected Map<Object, Object> childValue(Map<Object, Object> parentValue) {
if (parentValue != null) {
return (Map<Object, Object>) ((HashMap<Object, Object>) parentValue).clone();
} else {
return null;
}
}
}
}

@ -51,6 +51,24 @@
<version>2.6</version>
<scope>compile</scope>
</dependency>
<!--shiro 核心-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>

@ -1,10 +1,20 @@
package com.bjmashibing.shiro;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@MapperScan(basePackages = {"com.bjmashibing.shiro.moduler.mapper"})
//开启AopContext.currentProxy()增强
@EnableAspectJAutoProxy(exposeProxy=true)
//开启springboot jdk动态代理方法
//@SpringBootApplication(exclude = { AopAutoConfiguration.class})
//@EnableTransactionManagement
@SpringBootApplication
public class ProxyApplication extends SpringBootServletInitializer {
public static void main(String[] args) {

@ -0,0 +1,23 @@
package com.bjmashibing.shiro.moduler.controller;
import org.springframework.web.bind.annotation.RestController;
import java.io.Serializable;
import java.util.Collection;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@RestController
public class UserController {
}

@ -0,0 +1,88 @@
package com.bjmashibing.shiro.moduler.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
private String username;
/**
*
*/
private String password;
/**
*
*/
private String secretkey;
private Integer locked;
/**
*
*/
private String realName;
/**
* :01
*/
private Integer isDelete;
/**
*
*/
private Date createTime;
/**
*
*/
private String createUser;
/**
*
*/
private Date updateUser;
/**
*
*/
private Date updateTime;
/**
*
*/
private Date ts;
}

@ -0,0 +1,17 @@
package com.bjmashibing.shiro.moduler.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjmashibing.shiro.moduler.entity.User;
import java.util.List;
/**
* <p>
* Mapper
* </p>
*
* @author
* @since 2020-04-13
*/
public interface UserMapper extends BaseMapper<User> {
}

@ -0,0 +1,28 @@
package com.bjmashibing.shiro.moduler.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjmashibing.shiro.moduler.entity.User;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
public interface UserService {
void aspectj1();
void aspectj2();
void parent();
void child();
}

@ -0,0 +1,71 @@
package com.bjmashibing.shiro.moduler.service.impl;
import com.bjmashibing.shiro.moduler.entity.User;
import com.bjmashibing.shiro.moduler.mapper.UserMapper;
import com.bjmashibing.shiro.moduler.service.UserService;
import com.bjmashibing.shiro.proxy.SysLog;
import org.springframework.aop.config.AopConfigUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author
* @since 2020-04-13
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@SysLog
@Override
public void aspectj1() {
System.out.println("aspectj1 执行。。。");
aspectj2();
//如何解决单独调用,注解不生效的情况
// ((UserService) AopContext.currentProxy()).aspectj2();
}
@SysLog
@Override
public void aspectj2() {
System.out.println("aspectj2 执行。。。");
}
@Override
@Transactional
public void parent() {
User parent = new User();
parent.setUsername("父亲");
userMapper.insert(parent);
// 工作中有这样的需求
//事务注解和异步注解都不生效
((UserService) AopContext.currentProxy()).child();
// testPrivate();
}
@Override
// @Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional() //根本就没生效
public void child() {
User child = new User();
child.setUsername("儿子");
userMapper.insert(child);
System.out.println(1 / 0);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
private void testPrivate(){
User child = new User();
child.setUsername("private");
userMapper.insert(child);
System.out.println(1 / 0);
}
}

@ -10,7 +10,7 @@ import org.springframework.context.annotation.Configuration;
* @author sunzhiqiang23
* @date 2019/9/27 13:42
*/
//@Configuration
@Configuration
public class AnnotationProcessorConfiguration {
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){

@ -14,10 +14,10 @@ public class AopLogMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getThis().getClass().getDeclaredMethod(invocation.getMethod().getName(),invocation.getMethod().getParameterTypes());
// SysLog sysLog = method.getAnnotation(SysLog.class);
// System.out.println("log: "+sysLog);
System.out.println("======");
return invocation.proceed();
Object proceed = invocation.proceed();
System.out.println(invocation);
System.out.println("记录日志");
return proceed;
}

@ -1,34 +1,21 @@
package com.bjmashibing.shiro.proxy;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
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.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.reflect.misc.MethodUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
/**
*
* <p></p>
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 201738 11:07:35
* @author sunzhiqiang23
* @date 2019/9/27 19:33
*/
@Aspect
@Component
//@Aspect
//@Component
public class SysLogAspect {
@Pointcut("@annotation(com.bjmashibing.shiro.proxy.SysLog)")
@ -41,7 +28,7 @@ public class SysLogAspect {
Object result =null ;
try {
result = point.proceed();
System.out.println("=============");
System.out.println("【记录日志】");
//执行时长(毫秒)
}catch (Exception e){
e.printStackTrace();

@ -1,12 +0,0 @@
package com.bjmashibing.shiro.service;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-06 17:40
*/
public interface UserService {
int add();
int select();
}

@ -1,27 +0,0 @@
package com.bjmashibing.shiro.service;
import com.bjmashibing.shiro.proxy.SysLog;
import org.springframework.stereotype.Service;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-06 17:41
*/
@Service
public class UserServiceImpl implements UserService{
@SysLog
@Override
public int add() {
System.out.println("添加用户");
select();
return 0;
}
@SysLog
@Override
public int select() {
System.out.println("查询用户");
return 0;
}
}

@ -0,0 +1,41 @@
# DataSource Config
spring:
datasource:
username: root
password: admin
url: jdbc:mysql://localhost:3306/db_shiro?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
driver-class-name: com.mysql.jdbc.Driver
#mybatis 插件
mybatis-plus:
mapper-locations: classpath:mapper/**/*.xml
#实体扫描多个package用逗号或者分号分隔
typeAliasesPackage: com.bjmashibing.shiro.moduler.*.entity
global-config:
db-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
# id-type: uuid
id-type: auto
# id-type: id_worker
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: 2
#驼峰下划线转换
db-column-underline: true
#刷新mapper 调试神器
refresh-mapper: true
#数据库大写下划线转换
#capital-mode: true
#序列接口实现类配置
# key-generator: com.baomidou.springboot.xxx
#逻辑删除配置
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
#自定义填充策略接口实现
# meta-object-handler: com.baomidou.springboot.xxx
#自定义SQL注入器
# sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true

@ -6,6 +6,8 @@ server:
min-spare-threads: 30
port: 80
spring:
profiles:
active: db
mvc:
static-path-pattern: /static/**
freemarker:

@ -5,4 +5,5 @@
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="com.bjmashibing.shiro" level="debug"/>
<logger name="org.springframework" level="debug" />
</configuration>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjmashibing.shiro.moduler.mapper.UserMapper">
</mapper>

@ -1,27 +0,0 @@
package com.bjmashibing.shiro;
import com.bjmashibing.shiro.service.UserService;
import com.bjmashibing.shiro.service.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-06 17:43
*/
@Slf4j
public class UserServiceTest extends ApplicationTests {
@Autowired
private UserService userService;
@Test
public void add(){
//userservice 真正运行的时候,是不是代理对象?
userService.add();
}
}

@ -0,0 +1,87 @@
package com.bjmashibing.shiro.mybatis;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.junit.jupiter.api.Test;
/**
* <br>
*
*
* @author:
* @create:2018-06-11 11:07
* @Modified BY:
**/
public class CodeGenerator {
@Test
public void generateCode() {
String packageName = "com.bjmashibing.shiro.moduler.system";
generateByTables( packageName, "sys_module","sys_role","sys_role_module_ref","sys_user","sys_user_role_ref");
}
private void generateByTables(boolean serviceNameStartWithI, String packageName, String... tableNames) {
GlobalConfig config = new GlobalConfig();
String dbUrl = "jdbc:mysql://127.0.0.1:3306/db_shiro";
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL)
.setUrl(dbUrl)
.setUsername("root")
.setPassword("admin")
.setDriverName("com.mysql.jdbc.Driver")
.setTypeConvert(new MySqlTypeConvert() {
@Override
public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
System.out.println("转换类型:" + fieldType);
//将数据库中datetime转换成date
if ( fieldType.toLowerCase().contains( "datetime" ) ) {
return DbColumnType.DATE;
}
if ( fieldType.toLowerCase().contains( "timestamp" ) ) {
return DbColumnType.DATE;
}
return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
}
});
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig
.setCapitalMode(true)
.setEntityLombokModel(true)
.setNaming(NamingStrategy.underline_to_camel)
.setInclude(tableNames).setTablePrefix("base_","test_","sys_","flow_","tbl_","jd_");//修改替换成你需要的表名,多个表名传数组
config.setActiveRecord(false)
.setAuthor("孙志强")
.setEnableCache(false)
.setOutputDir("D:\\export")
.setFileOverride(true);
//user -> UserService, 设置成true: user -> IUserService
if (!serviceNameStartWithI) {
config.setServiceName("%sService");
}
new AutoGenerator()
.setTemplateEngine(new FreemarkerTemplateEngine())
.setGlobalConfig(config)
.setDataSource(dataSourceConfig)
.setStrategy(strategyConfig)
.setPackageInfo(
new PackageConfig()
.setParent(packageName)
.setController("controller")
.setEntity("entity")
).execute();
}
private void generateByTables(String packageName, String... tableNames) {
generateByTables(false, packageName, tableNames);
}
}

@ -0,0 +1,49 @@
package com.bjmashibing.shiro.patterns.builder;
import java.util.Date;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-13 17:28
*/
public class SubjectBuilder {
private int id = 1;
private String firstname = "first";
private String lastname = "last";
private Date birthdate = new Date();
private String street = "street";
public SubjectBuilder(int id, String firstname, String lastname, Date birthdate, String street) {
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
this.birthdate = birthdate;
this.street = street;
}
public SubjectBuilder Build() {
return new SubjectBuilder(id, firstname, lastname, birthdate, street);
}
public SubjectBuilder WithFirstName(String firstname) {
this.firstname = firstname;
return this;
}
public SubjectBuilder WithLastName(String lastname) {
this.lastname = lastname;
return this;
}
public SubjectBuilder WithBirthDate(Date birthdate) {
this.birthdate = birthdate;
return this;
}
public SubjectBuilder WithStreet(String street) {
this.street = street;
return this;
}
}

@ -0,0 +1,22 @@
package com.bjmashibing.shiro.patterns.builder;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-13 17:36
*/
public class TestSubjectBuilder {
public static void main(String[] args) {
SecurityManager securityManager = new DefaultSecurityManager();
Subject subject1 = new Subject.Builder(securityManager).authenticated(false).buildSubject();
Subject subject2 = new Subject.Builder(securityManager).authenticated(true).buildSubject();
System.out.println(subject1.isAuthenticated());
System.out.println(subject2.isAuthenticated());
}
}

@ -1,4 +1,4 @@
package com.bjmashibing.shiro.proxy;
package com.bjmashibing.shiro.patterns.proxy;
import org.junit.jupiter.api.Test;
import org.springframework.cglib.proxy.Enhancer;

@ -1,4 +1,4 @@
package com.bjmashibing.shiro.proxy;
package com.bjmashibing.shiro.patterns.proxy;
import org.springframework.aop.interceptor.PerformanceMonitorInterceptor;

@ -1,4 +1,4 @@
package com.bjmashibing.shiro.proxy;
package com.bjmashibing.shiro.patterns.proxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

@ -0,0 +1,29 @@
package com.bjmashibing.shiro.patterns.proxy.springaop;
import com.bjmashibing.shiro.ApplicationTests;
import com.bjmashibing.shiro.moduler.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-09 20:41
*/
public class AnnotationTest extends ApplicationTests {
@Autowired
private UserService userService;
@Test
public void testAspectOnly(){
userService.aspectj2();
userService.aspectj2();
}
@Test
public void testAspectMany(){
userService.aspectj1();
}
}

@ -0,0 +1,18 @@
package com.bjmashibing.shiro.patterns.proxy.springaop;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-13 14:48
*/
public class BeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("代理方法执行:"+method.getName());
}
}

@ -0,0 +1,27 @@
package com.bjmashibing.shiro.patterns.proxy.springaop;
import com.bjmashibing.shiro.moduler.service.UserService;
import com.bjmashibing.shiro.moduler.service.impl.UserServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.aop.framework.ProxyFactory;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-13 14:47
*/
public class SpringAdviceTest {
@Test
public void testAdvice() {
UserService target = new UserServiceImpl();
BeforeAdvice beforeAdvice = new BeforeAdvice();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvice(beforeAdvice);
UserService proxy = (UserService) proxyFactory.getProxy();
proxy.aspectj1();
}
}

@ -0,0 +1,22 @@
package com.bjmashibing.shiro.patterns.proxy.springaop;
import com.bjmashibing.shiro.ApplicationTests;
import com.bjmashibing.shiro.moduler.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
/**
* <p></p>
*
* @author sunzhiqiang23
* @date 2020-06-09 21:45
*/
public class UserServiceTest extends ApplicationTests {
@Autowired
private UserService userService;
@Test
public void test(){
userService.parent();
}
}

@ -41,6 +41,7 @@ public class UserController {
User user = ShiroUtils.getUser();
ModelAndView mv = new ModelAndView("/user");
mv.addObject("user", user);
return mv;
}

Binary file not shown.
Loading…
Cancel
Save