• JavaEE、Spring


     

    目录

    一、Spring系统架构

    二、核心概念

     三、IoC入门案例

     四、DI入门案例

    五、bean (使用XML配置bean)

    1、基础配置

     2、bean别名配置

     3、bean作用范围

    4、bean的实例化

    1、通过构造器实例化bean

    2、通过静态工厂实例化bean

    3、通过实例工厂实例化bean

    4、通过BeanFactory实例化bean(基于第三种方式改良)(重要!)

    5、bean的生命周期

     六、依赖注入

    1、依赖注入的方式

    1、setter注入

    使用setter注入基本类型

    使用setter注入引用类型

    2、构造器注入

    使用构造器注入引用类型

     使用构造器注入基本类型

    2、依赖注入的方式选择

    3、依赖自动装配

    1、使用类型(byType)自动装配

    2、使用名称(byName)自动装配

     4、集合注入

    5、管理数据源对象

    6、Spring加载properties文件

     七、容器

    1、创建容器

    2、获取bean

    3、ApplicationContext实现类

    八、核心容器、bean与依赖注入总结

    九、注解开发

    1、注解开发定义bean

     2、纯注解开发

      3、注解中bean的管理

    1、bean的作用范围

     2、bean的生命周期

    4、使用注解依赖注入

    1、自动装配

             2、注解加载外部文件

     5、注解中第三方bean的管理

    6、对外部bean依赖注入

    1、注入简单类型

     2、注入引用类型

     7、注解开发总结

    十、Sping整合其他框架

    1、Spring整合MyBatis

    2、Sping整合Junit

    十一、AOP

    1、AOP入门案例

    2、AOP工作流程

    3、AOP切入点表达式

    1、切入点表达式规则

    2、切入点表达式通配符

    3、书写技巧

    4、AOP通知类型(切面注解)

    5、AOP通知获取数据

    6、AOP案例:百度网盘分享链接输入密码AOP处理

    7、AOP总结

     十二、Spring事务

     Spring事务角色


    一、Spring系统架构

    二、核心概念

    当前书写代码存在的问题:业务层中要使用Dao层的实现类就需要new一个实现类对象,如果这时又来一个实现类对象就要修改业务层代码,有需要重新编译测试,代码耦合度极高

     使用IoC控制反转将对象的创建权交给外部,不要再new一个对象

     

     三、IoC入门案例

    1. <dependency>
    2. <groupId>org.springframeworkgroupId>
    3. <artifactId>spring-contextartifactId>
    4. <version>5.3.16version>
    5. dependency>
    1. <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" />
    2. <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    3. bean>
    1. public class BookServiceImpl implements BookService {
    2. private BookDao bookDao = new BookDaoImpl();
    3. @Override
    4. public void save() {
    5. System.out.println("bookservice");
    6. bookDao.save();
    7. }
    8. }

     四、DI入门案例

    由于在service中仍然new了dao的对象才能调用dao方法,没有实现真正解耦

    1. <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" />
    2. <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    3. <property name="bookDao" ref="bookDao">property>
    4. bean>
    1. public class BookServiceImpl implements BookService {
    2. //仍然new了实现类对象才能进行数据交互
    3. //private BookDao bookDao = new BookDaoImpl();
    4. //1、删除new的实现类对象
    5. private BookDao bookDao;
    6. @Override
    7. public void save() {
    8. System.out.println("bookservice");
    9. bookDao.save();
    10. }
    11. //2、创建setBookDao方法
    12. public void setBookDao(BookDao bookDao){
    13. this.bookDao = bookDao;
    14. }
    15. }

    五、bean (使用XML配置bean)

    1、基础配置

     2、bean别名配置

     3、bean作用范围

    可以看到虽然表面创建了两个不同的Dao对象,但他们都指向同一个bean ,所以bean的作用范围默认为单例,因为如果是非单例,每使用一次这个bean都会再重新创建一次这个bean会使得容器中的bean越来越多

     可以通过scope属性设置非单例

    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"/>

    4、bean的实例化

    1、通过构造器实例化bean

    1. public class BookDaoImpl implements BookDao {
    2. public BookDaoImpl() {
    3. System.out.println("bookdaoimpl构造器被调用");
    4. }
    5. @Override
    6. public void save() {
    7. System.out.println("bookdao");
    8. }
    9. }

    可以看到Spring对bean进行实例化会默认通过无参构造器创建bean对象,通过反射实现

    2、通过静态工厂实例化bean

    1. public class BookDaoFactory {
    2. //创建一个BookDao 工厂,提供创建BookDaoImpl的方法
    3. public static BookDao getBookDao(){
    4. System.out.println("factory start");
    5. return new BookDaoImpl();
    6. }
    7. }
    1. <bean id="bookDao" class="com.itheima.factory.BookDaoFactory" factory-method="getBookDao">bean>

    3、通过实例工厂实例化bean

    1. public class BookDaoFactory2 {
    2. //创建实例工厂
    3. public BookDao getBookDao(){
    4. System.out.println("实例工厂被调用");
    5. return new BookDaoImpl();
    6. }
    7. }
    1. <bean id="BookFactory" class="com.itheima.factory.BookDaoFactory2">bean>
    2. <bean id="bookDao" factory-method="getBookDao" factory-bean="BookFactory">bean>

    4、通过BeanFactory实例化bean(基于第三种方式改良)(重要!)

    1. //实现FactoryBean接口,声明泛型类型,可能还有其他的bean需要实例化只需要修改泛型类型即可
    2. public class BookFactoryBean implements FactoryBean {
    3. @Override
    4. public BookDao getObject() throws Exception {
    5. System.out.println("factorybean 启动");
    6. //返回BookDao的实现类
    7. return new BookDaoImpl();
    8. }
    9. @Override
    10. public Class getObjectType() {
    11. //声明返回对象的类型
    12. return BookDao.class;
    13. }
    14. @Override
    15. public boolean isSingleton() {
    16. //此处为true说明实例化的对象为单例(同一个bean),false为非单例
    17. return true;
    18. }
    19. }
    1. <bean id="bookDao" class="com.itheima.factory.BookFactoryBean">bean>

    5、bean的生命周期

     六、依赖注入

    1、依赖注入的方式

    1、setter注入

    上节bean的实例化都是使用setter注入的方式进行

    • 使用setter注入基本类型

    1. public class BookServiceImpl2 implements BookService {
    2. //使用setter注入 注入基本类型
    3. private int maxLink;
    4. private String databaseName;
    5. public void setMaxLink(int maxLink) {
    6. this.maxLink = maxLink;
    7. }
    8. public void setDatabaseName(String databaseName) {
    9. this.databaseName = databaseName;
    10. }
    11. public void save() {
    12. System.out.println("bookservice被创建");
    13. System.out.println(maxLink +"..."+ databaseName);
    14. }
    15. }
    1. <bean id="bookService2" class="com.itheima.service.impl.BookServiceImpl2">
    2. <property name="maxLink" value="10"/>
    3. <property name="databaseName" value="uesr"/>
    4. bean>

    • 使用setter注入引用类型

    1. public class BookServiceImpl implements BookService {
    2. private BookDao bookDao;
    3. private UserDao userDao;
    4. //创建set方法
    5. public void setBookDao(BookDao bookDao) {
    6. this.bookDao = bookDao;
    7. }
    8. public void setUserDao(UserDao userDao) {
    9. this.userDao = userDao;
    10. }
    11. public void save() {
    12. System.out.println("bookservice被创建");
    13. bookDao.save();
    14. userDao.save();
    15. }
    16. }
    1. <bean id="bookdao" class="com.itheima.dao.impl.BookDaoImpl">bean>
    2. <bean id="userdao" class="com.itheima.dao.impl.UserDaoImpl">bean>
    3. <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    4. <property name="bookDao" ref="bookdao">property>
    5. <property name="userDao" ref="userdao">property>
    6. bean>

    2、构造器注入

    • 使用构造器注入引用类型

    1. public class BookServiceImpl3 implements BookService {
    2. //使用setter注入 注入基本类型
    3. private BookDao bookDao1;
    4. private UserDao userDao1;
    5. //使用构造器注入,设置构造器参数
    6. public BookServiceImpl3(BookDao bookDao1,UserDao userDao1) {
    7. this.bookDao1 = bookDao1;
    8. this.userDao1 = userDao1;
    9. }
    10. public void save() {
    11. System.out.println("bookservice被创建");
    12. bookDao1.save();
    13. userDao1.save();
    14. }
    15. }
    1. <bean id="bookService3" class="com.itheima.service.impl.BookServiceImpl3">
    2. <constructor-arg name="bookDao1" ref="bookdao"/>
    3. <constructor-arg name="userDao1" ref="userdao"/>
    4. bean>

    •  使用构造器注入基本类型

    仅仅修改配置文件中的ref  化成value

    但是当前构造器注入仍然存在紧耦合的问题,参数名一旦发生改变配置文件就要相对应的改变

    所以Spring给出了解决方案

    1. <bean id="bookService3" class="com.itheima.service.impl.BookServiceImpl3">
    2. <constructor-arg type="com.itheima.dao.BookDao" ref="bookdao"/>
    3. <constructor-arg type="com.itheima.dao.UserDao" ref="userdao"/>
    4. bean>

    但是使用这种方式也可能会出现参数类型相同的情况所以又引出了第二种解决方案

    1. <bean id="bookService3" class="com.itheima.service.impl.BookServiceImpl3">
    2. <constructor-arg index="0" ref="bookdao"/>
    3. <constructor-arg index="1" ref="userdao"/>
    4. bean>

    2、依赖注入的方式选择

    构造器注入是必须注入的,而setter注入是可选的可注可不注

    3、依赖自动装配

    1、使用类型(byType)自动装配

    2、使用名称(byName)自动装配

    1. <bean id="bookService4" class="com.itheima.service.impl.BookServiceImpl4" autowire="byName"/>
    1. public class BookServiceImpl4 implements BookService {
    2. //使用setter注入 注入基本类型
    3. private BookDao bookDao;
    4. private UserDao userDao;
    5. //使用setter方法设置自动装配入口
    6. public void setBookDao(BookDao bookDao) {
    7. this.bookDao = bookDao;
    8. }
    9. public void setUserDao(UserDao userDao) {
    10. this.userDao = userDao;
    11. }
    12. public void save() {
    13. System.out.println("bookservice被创建");
    14. bookDao.save();
    15. userDao.save();
    16. }
    17. }

     

     4、集合注入

     

     如果集合中要加入引用类型的数据将value改为ref

    5、管理数据源对象

    用IoC容器来管理外部导入的资源,例如druid数据库连接池,junit测试等依赖

    1. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    2. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    3. <property name="url" value="jdbc:mysql://localhost:3306"/>
    4. <property name="username" value="123"/>
    5. <property name="password" value="123"/>
    6. bean>

    6、Spring加载properties文件

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xmlns:context="http://www.springframework.org/schema/context"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans
    5. http://www.springframework.org/schema/beans/spring-beans.xsd
    6. http://www.springframework.org/schema/context
    7. http://www.springframework.org/schema/context/spring-context.xsd">
    8. <context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
    9. <bean class="com.alibaba.druid.pool.DruidDataSource">
    10. <property name="driverClassName" value="${jdbc.driverClassName}"/>
    11. <property name="url" value="${jdbc.url}"/>
    12. <property name="username" value="${jdbc.username}"/>
    13. <property name="password" value="${jdbc.password}"/>
    14. bean>
    15. beans>

     

     七、容器

    1、创建容器

    1. //1、使用类路径创建容器
    2. ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    3. //2、使用文件系统绝对路径创建容器
    4. ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\2ProgramTool\\JavaEETest\\stage1\\springdemo3\\src\\main\\resources\\jdbc.properties");

    2、获取bean

    3、ApplicationContext实现类

    ApplicationContext的祖宗接口就是BeanFactory

    八、核心容器、bean与依赖注入总结

     

     

    九、注解开发

    1、注解开发定义bean

     2、纯注解开发

     使用纯注解定义bean

    1. //1、创建配置类代替配置文件
    2. @Configuration //代表配置文件
    3. @ComponentScan("com.itheima") //代表包扫描组件
    4. @ComponentScan({"com.itheima","com.ittest"}) //在多个包扫描组件
    5. public class SpringConfig {
    6. //使用配置类代替配置文件
    7. }
    1. //2、定义bean
    2. @Repository("bookDao")
    3. public class BookDaoImpl implements BookDao {
    4. public void save() {
    5. System.out.println("注解开发");
    6. }
    7. }
    1. //3、使用bean
    2. public class App {
    3. public static void main(String[] args) {
    4. //使用纯注解开发将不再需要applicatinContext文件
    5. ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
    6. //通过组件名称
    7. BookDao bookDao = ctx.getBean("bookDao", BookDao.class);
    8. System.out.println(bookDao);
    9. }
    10. }

    3、注解中bean的管理

    1、bean的作用范围

     2、bean的生命周期

    4、使用注解依赖注入

    1、自动装配

    注入引用类型

    1. @Repository("bookDao")
    2. public class BookDaoImpl implements BookDao {
    3. @Autowired //默认按类型自动装配,不需要写setter入口
    4. @Qualifier("mappDao") //按名称装配
    5. private Mapp mapp;
    6. public void save() {
    7. System.out.println("bookDao被创建");
    8. mapp.save();
    9. }
    10. }

     注入基本类型

     2、注解加载外部文件

     5、注解中第三方bean的管理

    1. @Configuration //代表配置文件
    2. @ComponentScan("com.itheima") //代表扫描组件
    3. @PropertySource({"jdbc.properties","jdbc2.properties","jdbc3.properties","jdbc2-1.properties"})
    4. public class SpringConfig {
    5. //使用配置类代替配置文件
    6. @Bean //说明返回类型是一个bean
    7. public DataSource dataSource(){
    8. DruidDataSource ds = new DruidDataSource();
    9. ds.setDriverClassName("com.mysql.jdbc.Driver");
    10. ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
    11. ds.setName("root");
    12. ds.setPassword("root");
    13. return ds;
    14. }
    15. }

    在实际开发中,外部的bean一般另外创建一个类来创建bean,然后导入的方式加到配置文件中

    1. //1、单独创建一个类
    2. public class JdbcConfig {
    3. @Bean //说明返回类型是一个bean
    4. public DataSource dataSource(){
    5. DruidDataSource ds = new DruidDataSource();
    6. ds.setDriverClassName("com.mysql.jdbc.Driver");
    7. ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
    8. ds.setName("root");
    9. ds.setPassword("root");
    10. return ds;
    11. }
    12. }
    1. @Configuration //代表配置文件
    2. @Import(JdbcConfig.class) //导入外部bean 多个外部bean使用数组形式
    3. public class SpringConfig {
    4. //使用配置类代替配置文件
    5. }

    6、对外部bean依赖注入

    1、注入简单类型

     2、注入引用类型

    直接设置参数,会进行自动装配

     7、注解开发总结

    十、Sping整合其他框架

    1、Spring整合MyBatis

    导入坐标

    1. <dependency>
    2. <groupId>org.springframeworkgroupId>
    3. <artifactId>spring-jdbcartifactId>
    4. <version>5.3.16version>
    5. dependency>
    6. <dependency>
    7. <groupId>org.mybatisgroupId>
    8. <artifactId>mybatis-springartifactId>
    9. <version>1.3.0version>
    10. dependency>

     创建jdbc.properties外部文件

    1. driver=com.mysql.jdbc.Driver
    2. url=jdbc:mysql://localhost:3306/users?useSSL=false
    3. username=root
    4. password=12345

    设置数据源 jdbc连接数据库

    1. public class JdbcConfig {
    2. @Value("${driver}")
    3. private String driverClassName;
    4. @Value("${url}")
    5. private String url;
    6. @Value("${name}")
    7. private String name;
    8. @Value("${password}")
    9. private String password;
    10. @Bean
    11. public DataSource dataSource(){
    12. //创建jdbc的数据库连接池DataSource
    13. DruidDataSource ds = new DruidDataSource();
    14. ds.setDriverClassName(driverClassName);
    15. ds.setUrl(url);
    16. ds.setName(name);
    17. ds.setPassword(password);
    18. return ds;
    19. }
    20. }

    配置类

    1. @Configuration
    2. @ComponentScan("com.itheima")
    3. @PropertySource("jdbc.properties")
    4. @Import({JdbcConfig.class,MyBatisConfig.class})
    5. public class SpringConfig {
    6. }

    2、Sping整合Junit

     导入坐标

    1. <dependency>
    2. <groupId>org.springframeworkgroupId>
    3. <artifactId>spring-testartifactId>
    4. <version>5.3.16version>
    5. dependency>
    6. <dependency>
    7. <groupId>junitgroupId>
    8. <artifactId>junitartifactId>
    9. <version>4.12version>
    10. <scope>testscope>
    11. dependency>

     使用专用类运行器RunWith

    1. @RunWith(SpringJUnit4ClassRunner.class)
    2. //与配置类接通
    3. @ContextConfiguration(classes = SpringConfig.class)
    4. public class ServiceTest {
    5. @Autowired
    6. private AccountService accountService;
    7. @Test
    8. public void testSelectById(){
    9. System.out.println(accountService.selectById(2));
    10. }
    11. }

    十一、AOP

    1、AOP入门案例

     导入需要的坐标

    在导入spring-context时是默认自动导入aop的坐标

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframeworkgroupId>
    4. <artifactId>spring-contextartifactId>
    5. <version>5.3.16version>
    6. dependency>
    7. <dependency>
    8. <groupId>org.aspectjgroupId>
    9. <artifactId>aspectjweaverartifactId>
    10. <version>1.9.4version>
    11. dependency>
    12. dependencies>
    1. //6、创建bean
    2. @Component
    3. //7、将这个bean作为AOP处理
    4. @Aspect
    5. public class MyAdvice {
    6. //2、创建通知类 定义通知方法
    7. //4、定义切入点
    8. @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    9. private void pt(){}
    10. //5、设置切入点的位置,作为切面绑定通知与切入点的关系
    11. @Before("pt()")
    12. public void advice(){
    13. //3、共性方法 通知
    14. System.out.println(System.currentTimeMillis());
    15. }
    16. }
    1. @Configuration
    2. @ComponentScan("com.itheima")
    3. //8、启动Aspect注解,开启AOP代理自动配置
    4. @EnableAspectJAutoProxy
    5. public class SpringConfig {
    6. }

    2、AOP工作流程

    底层是代理模式增强功能

     

    3、AOP切入点表达式

    1、切入点表达式规则

     

    2、切入点表达式通配符

     

    3、书写技巧

     

    4、AOP通知类型(切面注解)

     

    1. @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    2. private void pt(){}
    3. @Pointcut("execution(int com.itheima.dao.BookDao.select())")
    4. private void pt2(){}
    5. //1、前置通知
    6. // @Before("pt()")
    7. public void advice(){
    8. System.out.println("before is running...");
    9. }
    10. //2、后置通知
    11. // @After("pt()")
    12. public void after(){
    13. System.out.println("after is running...");
    14. }
    15. //3、环绕通知
    16. @Around("pt2()")
    17. public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    18. System.out.println("before running...");
    19. //调用原始方法
    20. //Object proceed = joinPoint.proceed();
    21. //还要将原始方法的返回值返回出去
    22. Integer proceed = (Integer) joinPoint.proceed();
    23. System.out.println("after running...");
    24. //还可以对原始方法的返回值进行修改
    25. return proceed;
    26. }

    5、AOP通知获取数据

    获取原始方法的参数数组,可以对参数进行修改,注意如果使用了JoinPoint作为参数一定要放在参数最前面。

     6、AOP案例:百度网盘分享链接输入密码AOP处理

     

    1. @Component
    2. @Aspect
    3. public class BaiduAop {
    4. @Pointcut("execution(boolean com.itheima.service.*Service.judgement(*,*))")
    5. public void pt(){}
    6. @Around("BaiduAop.pt()")
    7. public Object trimStr(ProceedingJoinPoint pjp) throws Throwable {
    8. //获取参数数据
    9. Object[] args = pjp.getArgs();
    10. //对参数数组遍历,对字符串类型的参数进行trim处理
    11. for (int i = 0; i < args.length; i++) {
    12. if (args[i].getClass().equals(String.class)){
    13. //如果是字符串就处理并修改参数
    14. args[i] = args[i].toString().trim();
    15. }
    16. }
    17. //将修改后的参数再传递给原始函数
    18. Object proceed = pjp.proceed(args);
    19. return proceed;
    20. }
    21. }

    7、AOP总结

     

     十二、Spring事务

     

     

     

     

     Spring事务角色

     

  • 相关阅读:
    如何安装ubuntu22.04以及ubuntu各个版本配置国内源和ssh远程登录
    如何在 swgger 中设置连接前后端的 API 接口
    Navicat15工具连接PostgreSQL15失败
    聊一聊 golang 的测试与性能调优
    关于在线音乐软件设计与实现的答辩问题
    德克萨斯大学奥斯汀分校自然语言处理硕士课程汉化版(第八周) - 现代大语言模型
    365天挑战LeetCode1000题——Day 035 每日一题 + 二分查找 13
    计算机毕业设计Java网上投稿管理系统(源码+系统+mysql数据库+Lw文档)
    8条IM即时通讯开发iOS端移动网络调优建议
    微服务学习|Feign:快速入门、自定义配置、性能优化、最佳实践
  • 原文地址:https://blog.csdn.net/m0_56044262/article/details/126636830