feat: 补充缺失文件

This commit is contained in:
郝先瑞 2022-05-07 23:01:10 +08:00
parent ad0855dc8b
commit 1a7fc796b9
31 changed files with 1145 additions and 0 deletions

View File

@ -0,0 +1,8 @@
package com.youlai.lab.elasticsearch;
/**
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
* @date 2021/11/28 10:06
*/
public class Test {
}

View File

@ -0,0 +1,60 @@
package com.youlai.lab.spring;
import java.util.Objects;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/2/18 0018 20:50
*/
//@Component
public class Bean {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Bean() {
}
public Bean(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Bean{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Bean bean = (Bean) o;
return age == bean.age && Objects.equals(name, bean.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}

View File

@ -0,0 +1,32 @@
package com.youlai.lab.spring.DI;
import com.youlai.lab.spring.Bean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 演示通过set方法注入
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/2/18 0018 20:48
*/
@Slf4j
@Component
public class SetterService {
private Bean bean;
public SetterService(){
System.out.println("service create");
}
public void test(){
System.out.println(bean);
}
//通过autowired指定使用set方法完成注入
@Autowired
public void setDiSetterBean(Bean bean) {
System.out.println("通过autowired指定使用set方法完成注入");
this.bean = bean;
}
}

View File

@ -0,0 +1,23 @@
package com.youlai.lab.spring.aop;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 通过名称设置自动代理
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/25 0025 23:52
*/
@Configuration
public class MyBeanNameAutoProxyCreator {
@Bean
public BeanNameAutoProxyCreator creator(){
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
beanNameAutoProxyCreator.setBeanNames("userService");
beanNameAutoProxyCreator.setInterceptorNames("myAdvisor");
return beanNameAutoProxyCreator;
}
}

View File

@ -0,0 +1,21 @@
package com.youlai.lab.spring.aop;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/26 0026 0:24
*/
@Configuration
public class MyDefaultAdvisorAutoProxyCreator {
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
return new DefaultAdvisorAutoProxyCreator();
}
}

View File

@ -0,0 +1,13 @@
package com.youlai.lab.spring.aop;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* 使用注解开启自动代理
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/26 0026 0:31
*/
@EnableAspectJAutoProxy
public class MyEnableAspectJAutoProxy {
}

View File

@ -0,0 +1,33 @@
package com.youlai.lab.spring.aop;
import org.springframework.transaction.annotation.Transactional;
/**
* 测试匹配的切点
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/27 0027 21:23
*/
public class PointcutService {
public void m1(){
System.out.println("已匹配包路径:com.youlai.laboratory.spring.aop,类名:PointcutService 方法名:m1,参数无,返回无");
}
public String m2(){
System.out.println("已匹配包路径:com.youlai.laboratory.spring.aop,类名:PointcutService 方法名:m2,参数无,返回String");
return "OK";
}
public void m3(String args3){
System.out.println("已匹配包路径:com.youlai.laboratory.spring.aop,类名:PointcutService 方法名:m3,参数一个String,返回无");
}
@Transactional
public void m4(){
System.out.println("已匹配包路径:com.youlai.laboratory.spring.aop,类名:PointcutService 方法名:m4,参数无,返回无,一个@Transactional注解");
}
}

View File

@ -0,0 +1,24 @@
package com.youlai.lab.spring.aop.transactional;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
/**
* 事务管理器
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/26 0026 20:30
*/
//@Configuration
public class MyPlatformTransactionManager {
// 使用DataSourceTransactionManager来管理事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
return dataSourceTransactionManager;
}
}

View File

@ -0,0 +1,60 @@
package com.youlai.lab.spring.aop.transactional;
import com.youlai.common.base.BaseEntity;
import lombok.Data;
/**
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
* @date 2022/2/12 16:12
*/
@Data
public class UmsAddress extends BaseEntity {
private Long id;
/**
* 会员ID
*/
private Long memberId;
/**
* 收货人姓名
*/
private String consigneeName;
/**
* 收货人联系方式
*/
private String consigneeMobile;
/**
*
*/
private String province;
/**
*
*/
private String city;
/**
*
*/
private String area;
/**
* 详细地址
*/
private String detailAddress;
/**
* 邮编
*/
private String zipCode;
/**
* 是否默认地址(1:0:)
*/
private Integer defaulted;
}

View File

@ -0,0 +1,160 @@
package com.youlai.lab.spring.aop.transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import java.util.List;
/**
* 用户余额业务,用于演示事务
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/26 0026 19:42
*/
public class UmsMemberService {
@Autowired
PlatformTransactionManager transactionManager;
@Autowired
JdbcTemplate jdbcTemplate;
/**
* 查询用户余额
*/
public Long getBalance(Long id){
String sql = "select * from ums_member where id = ?";
RowMapper<UmsMember> rowMapper = new BeanPropertyRowMapper<>(UmsMember.class);
List<UmsMember> umsMemberList = jdbcTemplate.query(sql,rowMapper,id);
return umsMemberList.get(0).getBalance();
}
/**
*
* 扣减会员余额
* @会员id id
* @扣减的余额 balance
* @return
*/
public boolean deductBalance(Long id,Long balance,boolean flag){
return doDeductBalance(id, balance, flag);
}
/**
* 加了声明式事务的扣减会员余额
* @会员id id
* @扣减的余额 balance
* @return
*/
@Transactional(rollbackFor = Exception.class)
public boolean transactionalDeductBalance(Long id,Long balance,boolean flag){
return doDeductBalance(id, balance, flag);
}
/**
* 7种事务传播行为0:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_REQUIRED} spring默认的事务传播行为,必须运行在事务中,支持当前事务,如果当前没有事务就新建一个事务
* 7种事务传播行为1:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_SUPPORTS} 支持当前事务,如果当前没有事务,就以非事务的方式执行,如果有事务就在这个事务中执行
* 7种事务传播行为2:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_MANDATORY} 必须运行在事务中,支持当前事务,如果当前没有事务,就抛出异常
* 7种事务传播行为3:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_MANDATORY} 必须在他自己的事务中执行,如果存在当前事务,就把当前事务挂起,新建一个事务
* 7种事务传播行为4:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_NOT_SUPPORTED} 不会在事务中执行,以非事务的方式执行操作,如果当前存在事务,就把当前事务挂起
* 7种事务传播行为5:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_NEVER} 不会在事务中执行,以非事务的方式执行操作,如果当前存在事务,就抛出异常
* 7种事务传播行为6:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_NESTED} 如果当前存在事务,则在嵌套事务内执行,嵌套的事务可以单独的提交或回滚,如果当前没有事务,则新建一个事务,需要注意厂商对这种嵌套事务的传播行为的支持
* @会员id id
* @扣减的余额 balance
* @return
*/
public boolean propagaDeductBalance(Long id,Long balance,boolean flag,int propagation){
TransactionStatus transactionStatus = buildTransactionStatus(propagation,TransactionDefinition.ISOLATION_DEFAULT);
return doTransaction(id, balance, flag,transactionStatus);
}
/**
* 五种事务隔离级别 -1:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_DEFAULT} spring默认使用数据库的隔离级别
* 五种事务隔离级别 1:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_READ_UNCOMMITTED} 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读,幻读,不可重复读
* 五种事务隔离级别 2:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_DEFAULT} 允许读取并发事务已经提交的数据,可以阻止脏读,但是还是可能会发生幻读,不可重复读
* 五种事务隔离级别 4:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_DEFAULT} 对同一字段的多次读取结果都是一致的,除非数据是被事务本身自己所修改,可以阻止脏读,不可重复读,但幻读仍有可能发生
* 五种事务隔离级别 8:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_DEFAULT} 最高隔离级别,完全服从ACID的隔离级别,可以阻止脏读,不可重复读,幻读
*
* @param id
* @param balance
* @param flag
* @param isolation
* @return
*/
public boolean isolationDeductBalance(Long id,Long balance,boolean flag,int isolation){
TransactionStatus transactionStatus = buildTransactionStatus(TransactionDefinition.PROPAGATION_REQUIRED, isolation);
return doTransaction(id, balance, flag,transactionStatus);
}
/**
* 获取一个事务实例
* 获取出来的时候就标志这个事务已经开始了 {@link org.springframework.transaction.support.AbstractPlatformTransactionManager#startTransaction}
* @return
*/
public TransactionStatus buildTransactionStatus(int propagation,int isolation){
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setReadOnly(false);
//事务传播行为
transactionDefinition.setPropagationBehavior(propagation);
//隔离级别,-1表示使用数据库默认级别
transactionDefinition.setIsolationLevel(isolation);
// 根据此事务属性拿到一个事务实例 注意此处的入参是一个TransactionDefinition
TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
return transaction;
}
/**
* 执行一个扣减余额的事务
* @return
*/
public boolean doTransaction(Long id,Long balance,boolean flag,TransactionStatus transactionStatus){
boolean debuct = true;
try {
System.out.println("before transaction");
Long balance1 = this.getBalance(id);
System.out.println("before transaction balance: "+balance1);
System.out.println("transaction....");
deductBalance(id, balance, flag);
// 提交事务
transactionManager.commit(transactionStatus);
} catch (Exception e) {
// 若发现异常 事务进行回滚
transactionManager.rollback(transactionStatus);
e.printStackTrace();
debuct = false;
}
System.out.println("after transaction");
Long balance2 = this.getBalance(id);
System.out.println("after transaction balance: "+balance2);
return debuct;
}
/**
* 真正执行扣除余额的操作
* @param id
* @param balance
* @param flag
* @return
*/
private boolean doDeductBalance(Long id,Long balance,boolean flag){
String sql = "update ums_member set balance = balance - ? where id = ?";
int i = jdbcTemplate.update(sql, balance, id);
if(flag){
int x = 1/0;
}
return i>0;
}
}

View File

@ -0,0 +1,43 @@
package com.youlai.lab.spring.bean;
import org.springframework.beans.factory.FactoryBean;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-09 12:25
*/
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo;
@Override
public Car getObject() {
Car car = new Car();
String[] infos = carInfo.split(",");
car.setBrand(infos[0]);
car.setMaxSpeed(Integer.valueOf(infos[1]));
car.setPrice(Double.valueOf(infos[2]));
return car;
}
@Override
public Class<?> getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
public String getCarInfo() {
return carInfo;
}
public void setCarInfo(String carInfo) {
this.carInfo = carInfo;
}
}

View File

@ -0,0 +1,31 @@
package com.youlai.lab.spring.bean;
import org.springframework.context.Lifecycle;
/**
* 容器生命周期回调,必须容器显示调用strat方法启动
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/20 0020 16:06
*/
public class ILifecycle implements Lifecycle {
boolean isRunning;
@Override
public void start() {
isRunning = true;
System.out.println("容器开始启动");
}
@Override
public void stop() {
isRunning = false;
System.out.println("容器结束");
}
@Override
public boolean isRunning() {
return isRunning;
}
}

View File

@ -0,0 +1,22 @@
package com.youlai.lab.spring.bean.aware;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* 获取ApplicationContext
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/20 0020 20:36
*/
public class IApplicationContextAware implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("\n--------------------");
System.out.println("ApplicationContext:"+applicationContext);
System.out.println("--------------------");
}
}

View File

@ -0,0 +1,20 @@
package com.youlai.lab.spring.bean.aware;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
/**
* 获取当前bean的beanFactory
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/20 0020 19:32
*/
public class IBeanFactoryAware implements BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("当前beanFactory:"+beanFactory);
this.beanFactory = beanFactory;
}
}

View File

@ -0,0 +1,24 @@
package com.youlai.lab.spring.beanDefinition;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/2/18 0018 20:50
*/
public class BeanA {
@PreDestroy
public void destroy(){
System.out.println("生命周期回调方法在bean被销毁时调用");
}
@PostConstruct
public void afterPropertiesSet() {
System.out.println("生命周期回调方法在bean完成属性注入后调用");
}
}

View File

@ -0,0 +1,22 @@
package com.youlai.lab.spring.beanPostProcessor;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
/**
*
* 合并beanDefinition的回调
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/19 0019 22:23
*/
public class IMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
System.out.println("5---找出所需要注入的字段,同时做缓存"+beanName);
}
@Override
public void resetBeanDefinition(String beanName) {
System.out.println("BeanDefinition被修改后的回调,清楚容器中的缓存"+beanName);
}
}

View File

@ -0,0 +1,32 @@
package com.youlai.lab.spring.constructor;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* 多个@Autowired标注的构造器
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-15 14:56
*/
public class E {
private String name;
private A a;
@Autowired(required = false)
public E(String name, A a) {
this.name = name;
this.a = a;
System.out.println("一个参数A和参数name");
}
@Autowired(required = false)
public E(A a) {
this.a = a;
System.out.println("一个参数A构造器");
}
public E() {
System.out.println("无参");
}
}

View File

@ -0,0 +1,10 @@
package com.youlai.lab.spring.constructor;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-15 17:52
*/
public class G extends H implements J{
}

View File

@ -0,0 +1,10 @@
package com.youlai.lab.spring.constructor;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-15 17:56
*/
public interface J {
}

View File

@ -0,0 +1,14 @@
package com.youlai.lab.spring.create;
/**
* 使用无参构造器实例化bean
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/2/18 0018 22:52
*/
public class ConstructorService{
public ConstructorService() {
System.out.println("使用无参构造器实例化bean");
}
}

View File

@ -0,0 +1,15 @@
package com.youlai.lab.spring.event;
import org.springframework.context.ApplicationEvent;
/**
* 事件A
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/22 0022 20:14
*/
public class EventA extends ApplicationEvent {
public EventA(Object source) {
super(source);
}
}

View File

@ -0,0 +1,26 @@
package com.youlai.lab.spring.event;
import org.springframework.context.event.EventListener;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import java.util.concurrent.Executor;
/**
* 自定义事件分发器
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/22 0022 21:34
*/
public class EventMulticasterD extends SimpleApplicationEventMulticaster {
@Override
protected Executor getTaskExecutor() {
System.out.println("获取自定义的线程池执行异步");
return super.getTaskExecutor();
}
@EventListener
public void listener(EventD eventD){
System.out.println("接收到事件:"+eventD);
System.out.println("处理事件");
}
}

View File

@ -0,0 +1,18 @@
package com.youlai.lab.spring.event;
import org.springframework.context.event.EventListener;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/22 0022 20:27
*/
public class ListenerB {
@EventListener
public void listen(EventB eventB){
System.out.println("接收到事件:"+eventB);
System.out.println("处理事件");
}
}

View File

@ -0,0 +1,19 @@
package com.youlai.lab.spring.look.constructors;
import org.springframework.stereotype.Component;
/**
* 构造器注入的bean
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-09 10:29
*/
//@Component
public class B1 {
private A1 a1;
public B1(A1 a1) {
this.a1 = a1;
}
}

View File

@ -0,0 +1,33 @@
package com.youlai.lab.spring.look.prototype;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-09 9:08
*/
@Component
@Scope(value= ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class A3 {
private String username = "a";
private B3 b3;
public A3() {
System.out.println("实例化A2:"+this);
}
@Autowired
public void setB(B3 b3) {
System.out.println("注入属性B2:"+ b3);
this.b3 = b3;
}
}

View File

@ -0,0 +1,32 @@
package com.youlai.lab.spring.look.prototype;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-09 9:08
*/
@Component
@Scope(value= ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class B3 {
private String username = "b";
private A3 a3;
public B3() {
System.out.println("实例化B2:"+this);
}
@Autowired
public void setA(A3 a3) {
System.out.println("注入属性A2:"+ a3);
this.a3 = a3;
}
}

View File

@ -0,0 +1,29 @@
package com.youlai.lab.spring.look.setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-09 9:08
*/
@Component
public class A2 {
private String username = "a";
private B2 b2;
public A2() {
System.out.println("实例化A2:"+this);
}
@Autowired
public void setB(B2 b2) {
System.out.println("注入属性B2:"+b2);
this.b2 = b2;
}
}

View File

@ -0,0 +1,29 @@
package com.youlai.lab.spring.look.setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 说明描述
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-09 9:08
*/
@Component
public class B2 {
private String username = "b";
private A2 a2;
public B2() {
System.out.println("实例化B2:"+this);
}
@Autowired
public void setA(A2 a2) {
System.out.println("注入属性A2:"+a2);
this.a2 = a2;
}
}

View File

@ -0,0 +1 @@
http\://www.youlai.tech/schema/user=com.youlai.laboratory.spring.beanDefinition.UserNamespaceHandler

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="car"
class="com.youlai.lab.spring.bean.CarFactoryBean">
<property name="carInfo" value="超级跑车,400,200000"/>
</bean>
</beans>

View File

@ -0,0 +1,266 @@
package com.youlai.lab.spring;
import com.youlai.lab.spring.aop.*;
import com.youlai.lab.spring.aop.transactional.*;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
/**
* Aop测试类
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/25 0025 23:42
*/
public class AopTests {
/**
* EnableAspectJAutoProxy 自动代理实现过程
*/
@SneakyThrows
@Test
void enableAspectj(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(UserService.class,MyAnnotationAwareAspectJAutoProxyCreator.class,AspectJAop.class);
MyAnnotationAwareAspectJAutoProxyCreator creator = context.getBean(MyAnnotationAwareAspectJAutoProxyCreator.class);
UserService userService = new UserService();
//查找advisors类型的bean或者标注了@AspectJ注解的bean
List<Advisor> advisors = creator.findEligibleAdvisors(AspectJAop.class,"aspectJAop");
for (Advisor advisor:advisors){
System.out.println(advisor);
}
//
// Object o = creator.wrapIfNecessary(userService, "userService", "userService");
// ((UserService)o).test();
//创建代理对象
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(userService);
proxyFactory.addAdvice(ExposeInvocationInterceptor.INSTANCE);
proxyFactory.addAdvisors(advisors);
// 统一转换成环绕通知 适配器模式
List<Object> interceptionAdvice = proxyFactory.getInterceptorsAndDynamicInterceptionAdvice(UserService.class.getMethod("test"), UserService.class);
//创建调用链
MyAnnotationAwareAspectJAutoProxyCreator.MyReflectiveMethodInvocation invocation = MyAnnotationAwareAspectJAutoProxyCreator.createReflectiveMethodInvocation(null, userService, UserService.class.getMethod("test"), new Object[0], UserService.class, interceptionAdvice);
invocation.proceed();
}
/**
* aspectj切面
*/
@SneakyThrows
@Test
void aspectj(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AspectJAop.class,UserService.class);
context.getBean(UserService.class).test();
}
/**
* 切点表达式
*/
@Test
void pointcut(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyPointcut.class,PointcutService.class);
MyPointcut myPointcut = context.getBean(MyPointcut.class);
myPointcut.execution();
myPointcut.within();
myPointcut.thisI();
myPointcut.target();
myPointcut.args();
myPointcut.Itarget();
myPointcut.Iargs();
myPointcut.Iwithin();
myPointcut.Iannotation();
myPointcut.Ibean();
myPointcut.staticMethodMatcherPointcut();
}
/**
* 手动代理
* 使用proxyFactory通过编程创建AOP代理
*/
@Test
void proxyFactory(){
ProxyFactory factory = new ProxyFactory();
factory.setTarget(new UserService());
factory.addAdvisor(new MyPointcutAdvisor());
UserService userService = (UserService) factory.getProxy();
userService.test();
}
/**
* 定义自动代理器,通过名称自动代理
*/
@Test
void beanNameAutoProxyCreator(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyBeanNameAutoProxyCreator.class, MyPointcutAdvisor.class, UserService.class);
UserService userService = context.getBean(UserService.class);
userService.test();
}
/**
* 注册默认代理
* 只要有defaultAdvisorAutoProxyCreator这个bean,它就会自动识别所有Advisor中的PointCut进行代理
*/
@Test
void defaultAdvisorAutoProxyCreator(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyDefaultAdvisorAutoProxyCreator.class, MyPointcutAdvisor.class, UserService.class);
UserService userService = context.getBean(UserService.class);
userService.test();
}
/**
* 使用注解开启自动代理
* 底层通过添加{@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator},
* 重写了{@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()}方法即可以找到Advisor类型的bean也能把所有@Aspect注解标注的类扫描出来并生成Advisor
*/
@Test
void myEnableAspectJAutoProxy(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyEnableAspectJAutoProxy.class, MyPointcutAdvisor.class,UserService.class);
UserService userService = context.getBean(UserService.class);
userService.test();
}
/**
*编程式使用事务方式1:使用TransactionTemplate
*/
@Test
void transactionTemplate(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JdbcConfig.class, MyTransactionTemplate.class, UmsMemberService.class);
UmsMemberService umsMemberService = context.getBean(UmsMemberService.class);
TransactionTemplate transactionTemplate = context.getBean(TransactionTemplate.class);
System.out.println("before transaction");
Long balance = umsMemberService.getBalance(39L);
System.out.println("before transaction balance: "+balance);
System.out.println("transaction....");
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try{
umsMemberService.deductBalance(39L,100l,true);
}catch (Exception e){
status.setRollbackOnly();
e.printStackTrace();
}
}
});
System.out.println("after transaction");
Long balance1 = umsMemberService.getBalance(39L);
System.out.println("after transaction balance: "+balance1);
}
/**
* 编程式使用事务方式2:使用PlatformTransactionManager
*/
@Test
void platformTransactionManager(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JdbcConfig.class, MyPlatformTransactionManager.class, UmsMemberService.class);
PlatformTransactionManager transactionManager = context.getBean(PlatformTransactionManager.class);
UmsMemberService umsMemberService = context.getBean(UmsMemberService.class);
// 构造一个准备使用此事务的定义信息~~~
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setReadOnly(false);
//隔离级别,-1表示使用数据库默认级别
transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// 根据此事务属性拿到一个事务实例 注意此处的入参是一个TransactionDefinition
TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
try {
System.out.println("before transaction");
Long balance = umsMemberService.getBalance(39L);
System.out.println("before transaction balance: "+balance);
System.out.println("transaction....");
umsMemberService.deductBalance(39L,100L,true);
// 提交事务
transactionManager.commit(transaction);
} catch (Exception e) {
// 若发现异常 事务进行回滚
transactionManager.rollback(transaction);
e.printStackTrace();
}
System.out.println("after transaction");
Long balance1 = umsMemberService.getBalance(39L);
System.out.println("after transaction balance: "+balance1);
}
/**
* 声明式事务管理
*/
@Test
void transactional(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MytransactionManager.class,JdbcConfig.class, UmsMemberService.class);
UmsMemberService umsMemberService = context.getBean(UmsMemberService.class);
System.out.println("before transaction");
Long balance = umsMemberService.getBalance(39L);
System.out.println("before transaction balance: "+balance);
System.out.println("transaction....");
try {
umsMemberService.transactionalDeductBalance(39L,100l,true);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("after transaction");
Long balance1 = umsMemberService.getBalance(39L);
System.out.println("after transaction balance: "+balance1);
}
/**
* 事务的7种事务传播行为
* 0:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_REQUIRED} spring默认的事务传播行为,必须运行在事务中,支持当前事务,如果当前没有事务就新建一个事务
* 1:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_SUPPORTS} 支持当前事务,如果当前没有事务,就以非事务的方式执行,如果有事务就在这个事务中执行
* 2:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_MANDATORY} 必须运行在事务中,支持当前事务,如果当前没有事务,就抛出异常
* 3:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_MANDATORY} 必须在他自己的事务中执行,如果存在当前事务,就把当前事务挂起,新建一个事务
* 4:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_NOT_SUPPORTED} 不会在事务中执行,以非事务的方式执行操作,如果当前存在事务,就把当前事务挂起
* 5:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_NEVER} 不会在事务中执行,以非事务的方式执行操作,如果当前存在事务,就抛出异常
* 6:{@link org.springframework.transaction.TransactionDefinition#PROPAGATION_NESTED} 如果当前存在事务,则在嵌套事务内执行,嵌套的事务可以单独的提交或回滚,如果当前没有事务,则新建一个事务,需要注意厂商对这种嵌套事务的传播行为的支持
*/
@Test
void propagation(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MytransactionManager.class,JdbcConfig.class, UmsMemberService.class);
UmsMemberService umsMemberService = context.getBean(UmsMemberService.class);
// umsMemberService.propagaDeductBalance(39L,100l,true,TransactionDefinition.PROPAGATION_REQUIRED);
// umsMemberService.propagaDeductBalance(39L,100l,true,TransactionDefinition.PROPAGATION_SUPPORTS);
// umsMemberService.propagaDeductBalance(39L,100l,true,TransactionDefinition.PROPAGATION_MANDATORY);
// umsMemberService.propagaDeductBalance(39L,100l,true,TransactionDefinition.PROPAGATION_REQUIRES_NEW);
// umsMemberService.propagaDeductBalance(39L,100l,true,TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
// umsMemberService.propagaDeductBalance(39L,100l,true,TransactionDefinition.PROPAGATION_NEVER);
umsMemberService.propagaDeductBalance(39L,100l,true,TransactionDefinition.PROPAGATION_NESTED);
}
/**
* 五种事务隔离级别 -1:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_DEFAULT} spring默认使用数据库的隔离级别
* 五种事务隔离级别 1:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_READ_UNCOMMITTED} 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读,幻读,不可重复读
* 五种事务隔离级别 2:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_DEFAULT} 允许读取并发事务已经提交的数据,可以阻止脏读,但是还是可能会发生幻读,不可重复读
* 五种事务隔离级别 4:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_DEFAULT} 对同一字段的多次读取结果都是一致的,除非数据是被事务本身自己所修改,可以阻止脏读,不可重复读,但幻读仍有可能发生
* 五种事务隔离级别 8:{@link org.springframework.transaction.TransactionDefinition#ISOLATION_DEFAULT} 最高隔离级别,完全服从ACID的隔离级别,可以阻止脏读,不可重复读,幻读
*/
@Test
void isolation(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MytransactionManager.class,JdbcConfig.class, UmsMemberService.class);
UmsMemberService umsMemberService = context.getBean(UmsMemberService.class);
// umsMemberService.isolationDeductBalance(39L,100L,Boolean.TRUE,TransactionDefinition.ISOLATION_DEFAULT);
// umsMemberService.isolationDeductBalance(39L,100L,Boolean.TRUE,TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
// umsMemberService.isolationDeductBalance(39L,100L,Boolean.TRUE,TransactionDefinition.ISOLATION_READ_COMMITTED);
// umsMemberService.isolationDeductBalance(39L,100L,Boolean.TRUE,TransactionDefinition.ISOLATION_REPEATABLE_READ);
umsMemberService.isolationDeductBalance(39L,100L,Boolean.TRUE,TransactionDefinition.ISOLATION_SERIALIZABLE);
}
}