【study】Spring学习part01
- 传统JavaWeb开发的困惑
- IoC、DI和AOP思想提出
- Spring框架诞生
传统JavaWeb开发的困惑以及解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public void updateUserInfo(User user) { try { DaoUtils.openTransaction(); UserDao userDao = new UserDaoImpl(); userDao.updateUserInfo(user); UserLog userLog = new UserLogImpl(); UserLog.recodeUserUpdate(user); DaoUtils.commit(); } catch(Exception e) { DaoUtils.rollback(); ExceptionLog exceptionLog = new ExceptionLogImpl(); exceptionLog.recodeException(this, e); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public void regist(User user) { try { DaoUtils.openTransaction(); UserDao userDao = new UserDaoImpl(); userDao.addUser(user); UserLog userLog = new UserLogImpl(); UserLog.recodeUserRegist(user); CommonUtils.sendEmail(user); DaoUtils.commit(); } catch(Exception e) { DaoUtils.rollback(); ExceptionLog exceptionLog = new ExceptionLogImpl(); exceptionLog.recodeException(this, e); } }
|
代码是两个业务层的代码, 主业务均为第7~8行
现在存在一些问题: 以updateUserInfo()
方法举例
1 2 3
| UserDao userDao = new UserDaoImpl(); UserLog userLog = new UserLogImpl(); ExceptionLog exceptionLog = new ExceptionLogImpl();
|
这里面耦合度很高:
IoC思想
Inversion of Control,控制反转,强调的是原来在程序中创建Bean的权利反转给第三方
DI思想
Dependency Injection,依赖注入,强调的Bean之间关系,这种关系第三方负责去设置
AOP思想
Aspect Oriented Programming,面向切面编程,功能的横向抽取,主要的实现方式是Proxy
基于XML管理Bean
IDE中新建Java项目,并且新建子模块day01
, 父模块中的pom.xml
引入一些依赖
==jdk版本: 21.0.2==
1 2 3 4 5 6 7 8 9 10 11 12 13
| <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.1.2</version> </dependency>
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.8.2</version> </dependency> </dependencies>
|
建立一些简单的文件
在day01.src.main.java.org.example
文件夹下
1 2 3 4 5 6 7
| package org.example.service;
public interface UserService { void add(); }
|
1 2 3 4 5 6 7 8 9 10 11
| package org.example.service.impl;
import org.example.service.UserService;
public class UserServiceImpl implements UserService { public void add() { System.out.println("add......"); } }
|
day01/src/main/resources/
文件夹内添加xml配置文件, 文件名没有要求,这里叫做beans.xml
1 2 3 4 5 6 7 8
| <?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 class="org.example.service.impl.UserServiceImpl" id="userService">
</bean> </beans>
|
bean
标签中,class指定要创建对象的类,id是唯一标识
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class TestUserService { @Test public void testUserService() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService"); System.out.println(userService);
userService.add(); }
}
|
创建的对象会执行其构造函数。
创建好的对象会被放入到Map<String, BeanDefinition> beanDefinitionMap
key是唯一标识符,beans.xml
中的id
value是类的定义(描述)信息
Log4j2日志框架
日志信息优先级(由低到高)
- TRACE:追踪,是最低的日志级别,相当于追踪程序的执行
- DEBUG:调试一般在开发中,都将其设置为最低的日志级别
- INFO:信息,输出重要的信息,使用较多
- WARN:警告,输出警告的信息
- ERROR:错误,输出错误信息
- FATAL:严重错误
引入log4j2依赖
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j2-impl</artifactId> <version>2.20.0</version> </dependency>
|
配置log4j2,在day01.src.main.resources
下新建log4j2.xml
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
| <?xml version="1.0" encoding="UTF-8" ?> <configuration> <loggers> <root level="DEBUG"> <appender-ref ref="spring6log" /> <appender-ref ref="RollingFile"/> <appender-ref ref="log"/> </root> </loggers> <appenders> <console name="spring6log" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/> </console>
<File name="log" fileName="/Users/promise/Promise Code/Java/FinalWork/SpringStudy/day01/test.log" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" /> </File>
<RollingFile name="RollingFile" fileName="/Users/promise/Promise Code/Java/FinalWork/SpringStudy/day01/app.log" filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> <SizeBasedTriggeringPolicy size="50MB"/> <DefaultRolloverStrategy max="20"/> </RollingFile> </appenders> </configuration>
|
使用logger
在org/example/test/TestUserService.java
文件,自定义logger
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
| package org.example.test;
import org.example.service.UserService; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUserService { private Logger logger = LoggerFactory.getLogger(TestUserService.class); @Test public void testUserService() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService"); System.out.println(userService);
userService.add();
logger.info("执行调用成功**************"); }
}
|
