提交 b6970d25 编写于 作者: 郝先瑞

fix: `laboratory` 启动模块报错问题修复

上级 df73d340
......@@ -19,12 +19,6 @@
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
<!-- 配置读取 -->
<dependency>
<groupId>org.springframework.boot</groupId>
......@@ -56,13 +50,6 @@
</exclusions>
</dependency>
<!--rocketmq-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
......@@ -80,21 +67,6 @@
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>com.youlai</groupId>
<artifactId>oms-api</artifactId>
......
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.youlai.tech/schema/user"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.youlai.tech/schema/user"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:element name="user">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="userName" type="xsd:string"/>
<xsd:attribute name="email" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
http\://www.youlai.tech/schema/user=com.youlai.laboratory.spring.beanDefinition.UserNamespaceHandler
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:youlai="http://www.youlai.tech/schema/user"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.youlai.tech/schema/user classpath:META-INF/spring-youlai.xsd">
<youlai:user id="userBean" userName="chuan" email="2256222053@qq.com"/>
</beans>
<?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="no"
class="com.youlai.laboratory.spring.DI.ByDefaultService"/>
<bean id="bean" name="bean"
class="com.youlai.laboratory.spring.Bean"
/>
<bean id="byName"
class="com.youlai.laboratory.spring.DI.ByNameService" autowire="byName"/>
<bean id="byType"
class="com.youlai.laboratory.spring.DI.ByTypeService" autowire="byType"/>
<bean id="constructor"
class="com.youlai.laboratory.spring.DI.ByConstructorService" autowire="constructor"/>
</beans>
<?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.laboratory.spring.bean.CarFactoryBean">
<property name="carInfo" value="超级跑车,400,200000"/>
</bean>
</beans>
<?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="beanC"
class="com.youlai.laboratory.spring.beanDefinition.BeanC"
init-method="afterPropertiesSet"
destroy-method="destroy"
/>
<bean id="bean"
class="com.youlai.laboratory.spring.beanDefinition.BeanD">
<property name="name" value="youlai"/>
<property name="age" value="2"/>
</bean>
<bean id="parent"
class="com.youlai.laboratory.spring.Bean"
parent="bean">
<property name="age" value="1"/>
</bean>
</beans>
<?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="d"
class="com.youlai.laboratory.spring.constructor.D"
factory-method="create"/>
</beans>
<?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="serviceLocator"
class="com.youlai.laboratory.spring.create.FactoryBeanService"
/>
<bean id="factoryBeanService"
factory-bean="serviceLocator"
factory-method="createInstance"
/>
</beans>
<?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="factoryClassService"
class="com.youlai.laboratory.spring.create.FactoryClassService"
factory-method="createInstance"/>
</beans>
package com.youlai.laboratory.rocketmq;
import org.apache.rocketmq.common.message.Message;
import org.springframework.messaging.support.MessageBuilder;
import javax.annotation.Resource;
public class TestProducer {
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.aop.*;
import com.youlai.laboratory.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);
}
}
package com.youlai.laboratory.spring;
import com.google.common.base.Objects;
import com.youlai.laboratory.spring.beanDefinition.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* beandefinition属性测试
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/2/21 0021 7:02
*/
public class BeanDefinition {
@Autowired
@Qualifier("scope")
private Bean bean;
@Test
void scope() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Property.class);
Object scope1 = context.getBean("scope");
Object scope2 = context.getBean("scope");
System.out.println(scope1.equals(scope2)); //获取两个相同的bean
}
/**
* 原型模式的bean
*/
@Test
void prototype() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Property.class);
Object prototype1 = context.getBean("prototype");
Object prototype2 = context.getBean("prototype");
System.out.println(prototype1.equals(prototype2)); //获取两个不同的bean
}
/**
* 懒加载的bean
*/
@Test
void lazy() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Property.class);
System.out.println("-----加载配置结束------");
context.getBean("lazy"); //获取bean的时候才创建bean
}
/**
* 多个相同类型的bean,声明默认的bean
*/
@Test
void primary() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Property.class);
Bean bean = context.getBean(Bean.class, Bean.class); //如果注册多个相同类型的bean,不指定name的情况下获取primary的bean
System.out.println(bean);
}
/**
* 依赖bean
*/
@Test
void dependsOn() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Property.class);
Bean depends = context.getBean("depends", Bean.class); //depends依赖beanB,所以会在创建depends之前先创建beanB
}
@Test
void initMethodNameAndDestroyMethodNameA() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanA.class);
System.out.println("准备销毁bean");
context.close();
}
@Test
void initMethodNameAndDestroyMethodNameB() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanB.class);
System.out.println("准备销毁bean");
context.close();
}
@Test
void initMethodNameAndDestroyMethodNameC() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/beanDefinition/Property.xml");
System.out.println("准备销毁bean");
context.close();
}
/**
* 父子beanDefinition合并,参考:
* {@link org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(String beanName, org.springframework.beans.factory.config.BeanDefinition bd,org.springframework.beans.factory.config.BeanDefinition containingBd)}
*/
@Test
void parent() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/beanDefinition/Property.xml");
Bean bean = context.getBean("parent", Bean.class);
System.out.println(bean); //会合并父属性的值,但不会覆盖值
}
/**
* 条件注入,需要满足当前jdk版本为<1.8.0_312>
*/
@Test
void condition() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Property.class);
List<String> list = Arrays.stream(context.getBeanDefinitionNames()).filter(name -> name.equals("condition")).collect(Collectors.toList());
System.out.println(list.isEmpty());
}
/**
* 使用import注册bean
*/
@Test
void importBean() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Property.class);
System.out.println(context.getBean(ImportBean.class));
}
/**
* 注入指定名称的bean
*/
@Test
void qualifier(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Property.class);
Bean scope = context.getBean("scope", Bean.class);
System.out.println(Objects.equal(scope,bean));
}
/**
* 根据环境注入的bean
*/
@Test
void profile(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("prod");
//context.getEnvironment().setActiveProfiles("dev");
context.register(Property.class);
context.refresh();
Bean profile = context.getBean("profile", Bean.class);
}
/**
* 自定义xml标签
*/
@Test
void parseXml(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:META-INF/youlai-user.xml");
User user = applicationContext.getBean("userBean", User.class);
System.out.println(user);
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.beanPostProcessor.*;
import com.youlai.laboratory.spring.beanPostProcessor.Bean;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* 测试beanPostProcessor的作用和执行时机
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/19 0019 14:20
*/
public class BeanPostProcessorTests {
/**
* spring内部实现的beanPostProcessos,用来创建bean
*/
@Test
void beanPostProcessor(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
Bean.class,IBeanPostProcessor.class, IInstantiationAwareBeanPostProcessor.class,
ISmartInstantiationAwareBeanPostProcessor.class,IDestructionAwareBeanPostProcessor.class,
IMergedBeanDefinitionPostProcessor.class
);
context.close();
}
/**
* 常用的bean生命周期回调
*/
@Test
void avdiceTests(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(IBeanPostProcessor.class);
context.register(IInitializingBean.class);
context.register(IDisposableBean.class);
context.register(Bean.class);
context.getBeanDefinition("bean").setLazyInit(true);
context.refresh();
System.out.println("\n\n-------------------开始创建bean--------------------");
context.getBean(Bean.class);
context.close();
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.bean.*;
import com.youlai.laboratory.spring.bean.aware.*;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
*
* bean测试用例
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-09 13:08
*/
public class BeanTests {
/**
* 使用FactoryBean创建bean
*/
@Test
void factoryBean(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/bean/CarFactoryBean.xml");
// Object carFactoryBean = context.getBean("&car"); //获取创建bean的工厂
// System.out.println(carFactoryBean);
Object car = context.getBean("car");
System.out.println(car);
}
/**
* 容器开始和结束的回调接口
* Lifecycle接口必须显示调用容器start方法,才能执行预先定义的回调
* start的spring底层调用{@link org.springframework.context.support.DefaultLifecycleProcessor#doStart}
* stop的spring底层调用{@link org.springframework.context.support.DefaultLifecycleProcessor#doStop}
*/
@Test
void lifecycle(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ILifecycle.class);
context.start();
context.close();
}
/**
* 容器开始和结束的回调接口
* {@link org.springframework.context.SmartLifecycle}继承了Lifecycle和Phased,
* 相比Lifecycle多了自定义优先级功能和控制是否需要显示调用start
*
*/
@Test
void smartLifecycle(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ISmartLifecycle1.class, ISmartLifecycle2.class);
context.close();
}
/**
* 先执行BeanNameAware,BeanClassLoaderAware,BeanFactoryAware三个aware,再执行其他aware
* spring底层实现:{@link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods}
*/
@Test
void aware(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(IBeanNameAware.class, IBeanClassLoaderAware.class, IBeanFactoryAware.class);
}
/**
* 处理上面三个aware再执行其他aware
*参考{@link org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces}
*/
@Test
void atherAware(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(IApplicationContextAware.class, IApplicationStartupAware.class, IEnvironmentAware.class, IEmbeddedValueResolverAware.class);
}
/**
* 执行完aware接口后执行初始化方法
* 先执行实现InitializingBean接口的afterPropertiesSet方法,后执行initMethod方法
*/
@Test
void initializingBean(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(IInitializingBean.class);
}
/**
* 初始化方法执行完之后执行初始化后方法,AOP在这个地方完成
* 参考{@link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization}
*/
@Test
void afterInitialization(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(IInitializingBean.class,IBeanPostProcessor.class);
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.constructor.*;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 推断构造方法
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-14 8:50
*/
public class ConstructorTests {
/**
* 默认使用无参构造函数
*/
@Test
void wu(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(A.class);
}
/**
* 如果指定Autowired,则使用autowired标注的构造函数
*/
@Test
void autowired(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(A.class,B.class);
}
/**
* 自定义实例化方法{@link java.util.function.Supplier#get}
* 源码调用{@link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance}
*/
@Test
void supplier(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.registerBean(C.class,new C());
context.refresh();
context.getBean("c");
}
/**
* 如果指定了工厂方法,则使用工厂方法创建创建
*/
@Test
void factoryBean(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/constructor/Bean.xml");
Object d = context.getBean("d");
}
/**
* 多个@Autowired标注构造器,必须设置required为false,根据能找到的最多的参数bean选择构造器
*/
@Test
void autowired2(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(A.class, E.class);
}
/**
* 当有多个构造器时,根据计算匹配度得分选择构造器,选择得分低的
* 完全匹配,得分为0
* 父类得分为2
* 父类的父类得分为4
* 接口得分为1
*/
@Test
void constructor(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( F.class,G.class);
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.create.ConstructorService;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
*
* 三种实例化bean方式
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/2/18 0018 23:19
*/
public class CreateTests {
@Test
void constructor(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConstructorService.class);
}
@Test
void factoryMethod(){
ClassPathXmlApplicationContext xmlApplicationContext = new ClassPathXmlApplicationContext("classpath:spring/create/FactoryClass.xml");
}
@Test
void factoryBean(){
ClassPathXmlApplicationContext xmlApplicationContext = new ClassPathXmlApplicationContext("classpath:spring/create/FactoryBean.xml");
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.DI.ByConstructorService;
import com.youlai.laboratory.spring.DI.ByDefaultService;
import com.youlai.laboratory.spring.DI.ByNameService;
import com.youlai.laboratory.spring.DI.ByTypeService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试4种自动装配模型,默认no,(no,byName,byName,constructor)
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/2/19 0019 18:00
*/
@Slf4j
public class DIModeTest {
@Test
void noTest(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/DI/DIModel.xml");
applicationContext.refresh();
ByDefaultService no = applicationContext.getBean("no", ByDefaultService.class);
log.info("装配成功?{}", no.bean==null);
}
@Test
void byName(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/DI/DIModel.xml");
applicationContext.refresh();
ByNameService byName = applicationContext.getBean("byName", ByNameService.class);
log.info("装配成功?:{}",byName.bean != null);
}
@Test
void byType(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/DI/DIModel.xml");
applicationContext.refresh();
ByTypeService byType = applicationContext.getBean("byType", ByTypeService.class);
log.info("装配成功?:{}",byType.bean != null);
}
@Test
void constructor(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/DI/DIModel.xml");
applicationContext.refresh();
ByConstructorService constructor = applicationContext.getBean("constructor", ByConstructorService.class);
log.info("装配成功?:{}",constructor.getBean() != null);
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.DI.ConstructorService;
import com.youlai.laboratory.spring.DI.SetterService;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* 测试两种注入方式(构造器和setter)
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/2/18 0018 21:04
*/
public class DITypeTests {
@Test
void setter(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(Bean.class);
applicationContext.registerBean(SetterService.class);
applicationContext.refresh();
SetterService setterService = applicationContext.getBean(SetterService.class);
setterService.test();
}
@Test
void constructor(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(Bean.class);
applicationContext.registerBean(ConstructorService.class);
applicationContext.refresh();
ConstructorService constructorService = applicationContext.getBean(ConstructorService.class);
constructorService.test();
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.event.*;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* spring事件监听机制
* 添加监听器 参考:{@link org.springframework.context.event.EventListenerMethodProcessor#processBean}
* 初始化事件监听: {@link org.springframework.context.support.AbstractApplicationContext#initApplicationEventMulticaster}
* 推断事件类型: {@link org.springframework.context.event.SimpleApplicationEventMulticaster#resolveDefaultEventType}
* 根据事件类型获取对应的监听器:{@link org.springframework.context.event.AbstractApplicationEventMulticaster#getApplicationListeners}
* 执行监听逻辑: {@link org.springframework.context.event.SimpleApplicationEventMulticaster#invokeListener}
*
*
* 推断事件类型:
*
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/22 0022 20:18
*/
public class EventTests {
/**
* 发布一个事件
*
*/
@Test
void publisherA(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventListener.class);
context.publishEvent(new EventA("hello event"));
}
/**
* 发布一个用注解接收的事件
*/
@Test
void publisherB(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ListenerB.class);
context.publishEvent(new EventB("注解事件"));
}
/**
* 在发布一个事件,多个监听的情况下
* 用Order注解对监听事件排序,值越小越先执行
*/
@Test
void publisherC(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ListenerC.class);
context.publishEvent(new EventC("事件排序"));
}
/**
* 自定义事件分发器
*/
@Test
void publicsherD(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.registerBean("applicationEventMulticaster",EventMulticasterD.class);
context.refresh();
context.publishEvent(new EventD("自定义事件分发器"));
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.look.constructors.Config1;
import com.youlai.laboratory.spring.look.prototype.B3;
import com.youlai.laboratory.spring.look.prototype.Config3;
import com.youlai.laboratory.spring.look.setter.A2;
import com.youlai.laboratory.spring.look.setter.Config2;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* 循环依赖测试用例
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022-03-09 10:26
*/
public class LookTests {
/**
* 构造器方式注入的循环依赖spring无法解决
* 因为spring需要依赖构造器来实施例bean
*/
@Test
void constructor(){
try{
new AnnotationConfigApplicationContext(Config1.class);
}catch (UnsatisfiedDependencyException exception){
exception.getCause();
}
}
/**
* set方式存入的单例bean,spring使用三级缓存通过提前暴露实例对象地址解决循环依赖
* 一级缓存已经注册的bean: {@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.singletonObjects}
* 二级缓存已经实例化但未初始化的bean: {@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.earlySingletonObjects}
* 三级缓存正在实例化的工厂bean:{@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.singletonFactories}
* 因为AOP创建代理对象依赖原始对象所以需要第三级缓存
*/
@Test
void setter(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config2.class);
A2 a2 = context.getBean("a2", A2.class);
System.out.println(a2);
}
/**
* 原型模式的bean,因为每次都要创建新的bean,所以spring无法通过提前暴露原始对象的bean来解决循环依赖
*/
@Test()
void prototype(){
try{
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config3.class);
System.out.println(context.getBean("b3", B3.class));
}catch (UnsatisfiedDependencyException e){
e.getCause();
}
}
}
package com.youlai.laboratory.spring;
import com.youlai.laboratory.spring.beanFactoryPostProcessor.*;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* BeanFactoryPostProcessor用于操作BeanDefinition信息,在实例化bean之前操作
* 测试BeanFactoryPostProcessor执行顺序
* @author <a href="mailto:2256222053@qq.com">zc</a>
* @Date 2022/3/17 0017 21:56
*/
public class beanFactoryPostProcessorTests {
/**
*
* 参考实现 {@link org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors}
* 执行顺序
* 1:实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered接口的类的postProcessBeanDefinitionRegistry方法
* 2:实现了BeanDefinitionRegistryPostProcessor和Ordered接口的类的postProcessBeanDefinitionRegistry方法
* 3:实现了BeanDefinitionRegistryPostProcessor接口的类的postProcessBeanDefinitionRegistry方法
* 4:实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered接口的类的postProcessBeanFactory方法
* 5:实现了BeanDefinitionRegistryPostProcessor和Ordered接口的类的postProcessBeanFactory方法
* 6:实现了BeanDefinitionRegistryPostProcessor接口的类的postProcessBeanFactory方法
* 7:实现了BeanFactoryPostProcessor和PriorityOrdered接口的类的postProcessBeanFactory方法
* 8:实现了BeanFactoryPostProcessor和Ordered接口的类的postProcessBeanFactory方法
* 9:实现了BeanFactoryPostProcessor接口的类的postProcessBeanFactory方法
*
* 总结 BeanDefinitionRegistryPostProcessor>BeanFactoryPostProcessor
* PriorityOrdered>Ordered
*/
@Test
public void A(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(A.class, B.class, C.class, E.class, D.class,F.class);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册