Spring从入门到精通(二)

news2024/11/19 7:27:19

文章目录

  • 1.动态代理
    • 1.1 概念
    • 1.2 jdk动态代理(重点)
    • 1.3 基于子类的动态代理(了解)
  • 2.AOP
    • 2.1 概念
    • 2.2 springAop — 基于AspectJ技术
      • 2.2.1 AspectJ使用(XML)
      • 2.2.2 AspectJ使用(注解开发)
  • 3. JdbcTemplate
    • 3.1 JdbcTemplate的基本概述
    • 3.2 JdbcTemplate在spring的ioc中配置
      • (1)XML配置
      • (2)注解配置
      • (4)JdbcTemplate的CRUD操作
  • 4. Spring的事务管理
    • 4.1 Spring的事务管理的API
    • 4.2 配置编程式事务(了解)
    • 4.3 配置声明式事务(XML方式)(重点)
    • 4.4 配置声明式事务(注解方式)(重点)
    • 4.5 编程式事务与声明式事务对比

1.动态代理

1.1 概念

  • 作用: 将核心功能与辅助功能(事务、日志、性能监控代码)分离,达到核心业务功能更纯粹、辅助业务功能可复用。
  • 功能分离:
    在这里插入图片描述
  • 分类:
    • 基于接口的动态代理jdk
    • 基于子类的动态代理cglib
  • 两种代理的返回对象:
    • 基于接口的动态代理返回对象为代理接口类型(接口引用指向实现)
    • 基于子类的动态代理返回对象为代理类对象

1.2 jdk动态代理(重点)

(1)特点、作用、分类

  • 特点: 代理对象在程序的运行过程中创建
  • 作用: 不修改源码的基础上对目标类方法进行增强
  • 分类:
    • 基于接口的动态代理
      • 涉及的类:Proxy
      • 提供者:JDK官方

(2)使用

  • 如何创建代理对象

    • 使用Proxy类中的newProxyInstance方法
  • 创建代理对象的要求

    • 被代理类最少实现一个接口,如果没有则不能使用
  • newProxyInstance方法的参数

    • ClassLoader
      • 类加载器
      • 它是用于加载代理对象字节码的,和被代理对象使用相同的类加载器。
      • 固定写法(写被代理对象的类加载器
    • Class[ ]
      • 字节码数组
      • 它是用于让代理对象和被代理对象有相同的方法(只要两者都实现了同一个接口,那么两者的方法必然相同,所以我们传接口的字节码文件即可)。
      • 固定写法(写接口字节码文件
    • InvocationHandler
      • 处理器
      • 用于提供增强的代码,它是让我们写如何代理,我们一般都是写一个InvocationHandler接口的实现类。通常情况下都是匿名内部类,但不是必须的,此接口的实现类都是谁用谁写
  • InvocationHandler中invoke方法参数

    • @param proxy :当前代理对象的引用,一般很少用
    • @param method: 当前执行的方法(被代理的方法
    • @param args: 当前执行方法需要的参数
    • @return 和被代理对象一样的返回值,很少使用

(3)示例

  • 演示转账工程中,事务代理
  • 实现过程
    • 使用工厂普通方法产生代理对象
    • 配置bean.xml文件
    • 测试

1.使用工厂普通方法产生代理对象

public class BeanFactory {

//    需要使用到的依赖类
    private TransactionManager transactionManager;
    private AccountService accountService;  //被代理的对象

//    用于bean.xml注入(spring容器使用setter方法注入)
    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }
    public void setAccountService(AccountService accountService) {
        this.accountService = accountService;
    }

//    通过工厂创建方法
    public AccountService getBean(){
        AccountService proxy = (AccountService) Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                判断需要代理的方法
                if ("transfer".equals(method.getName())) {
                    try {
//                    开启事务
                        transactionManager.begin();
//                        利用反射实现被代理对象的方法调用
                        method.invoke(accountService,args);
//                    提交事务
                        transactionManager.commit();
                    } catch (Exception e) {
//                        回滚事务
                        transactionManager.rollback();
                        e.printStackTrace();
                    } finally {
//                        释放资源
                        transactionManager.realease();
                    }
                }
                return null;
            }
        });
        return proxy;
    }

}

2.配置bean.xml文件

<!--    工厂注册-->
    <bean id="beanFactory" class="com.qfedu.factory.BeanFactory">
        <property name="transactionManager" ref="transactionManager"></property>
        <property name="accountService" ref="accountService"></property>
    </bean>
<!--    使用工厂产生代理对象-->
    <bean id="proxy" class="com.qfedu.service.impl.AccountServiceImpl" factory-bean="beanFactory" factory-method="getBean"></bean>

3.测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:bean.xml" )
public class TestDemo01 {
    @Autowired
    @Qualifier("proxy")
    private AccountService accountService;

    @Test
    public void testProxy(){
        accountService.transfer("james","curry",100.0);
    }
}

1.3 基于子类的动态代理(了解)

  • 那我们要如何代理一个普通的Java类呢?我们可以使用基于子类的动态代理

(1)特点、作用、分类

  • 特点: 字节码随用随创建,随用随加载。
  • 作用: 不修改源码的基础上对目标类方法进行增强
  • 分类:
    • 第三方cglib库
    • 使用Enhancer类

(2)使用

  • 依赖的库(cglib)
	<dependency>
       <groupId>cglib</groupId>
       <artifactId>cglib</artifactId>
       <version>2.1_3</version>
    </dependency>
  • 如何创建代理对象

    • 使用Enhancer类中的create方法
  • 创建代理对象的要求

    • 被代理类不能是最终类(也就是这个类不能用final修饰,因为最终类不能创建子类)
  • create方法的参数

    • class:字节码
      • 它是用于指定被代理对象的字节码
    • callback:用于提供增强的代码
      • 我们一般写的都是callback接口的子接口实现类:MethodInterceptor(为方法拦截的意思)
  • MethodInterceptor实现类的intercept风法参数

    • @param o 当前代理对象的引用
    • @param method 代理对象需要执行的方法
    • @param objects 代理对象执行该方法需要用到的参数
    • @param methodProxy 当前执行方法的代理对象(不常用)
    • @return 返回值也是跟被代理对象执行方法的返回值一样
  • 示例:代理买电脑

1. 生产商(类—不实现接口)

public class Producer{

    public void buyProduct(String name) {
        System.out.println(name + "售卖了电脑");
    }
}

2. 代理商

/**
 * 消费者
 * 分别直接买
 * 让代理买
 */
public class Consumer {
    public static void main(String[] args) {
        final Producer producer = new Producer();
        Producer proxy = (Producer) Enhancer.create(Producer.class, new MethodInterceptor() {
            /**
             * @param o 当前代理对象的引用
             * @param method 代理对象需要执行的方法
             * @param objects 代理对象执行该方法需要用到的参数
             * @param methodProxy 当前执行方法的代理对象(不常用)
             * @return 返回值也是跟被代理对象执行方法的返回值一样
             * @throws Throwable
             */
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                if(method.getName().equals("buyProduct")){
					System.out.println("代理商对方法进行了增强");
                    method.invoke(producer,objects);
                }
                return null;
            }
        });
        //代理商对象调用
        proxy.buyProduct("经销商");
    }
}


2.AOP

2.1 概念

  • AOP面向切面编程把通用共有的功能抽取出来,降低耦合,通过动态代理的方式来去执行。
  • AOP利用的是一种横切技术,解剖开封装的对象内部,并将那些影响多个类的公共行为封装到一个可重用模块,这就是所谓的Aspect方面/切面。
  • 切面,简单点所说,就是将哪些与业务无关,却为业务模块所共同调用的行为(方法)提取封装,减少系统的重复代码,以达到逻辑处理过程中各部分之间低耦合的隔离效果。
  • AOP采取横向抽取机制,取代了传统的纵向继承体系重复性代码
    在这里插入图片描述

2.2 springAop — 基于AspectJ技术

(1)AspectJ简介

  • 使用AspectJ的原因
    • SpringAop的底层采用的是动态代理技术,但是动态代理(jdk动态代理 cglib字节码代理)过于繁琐。于是spring引入了第三方的AspectJ框架
  • AspectJ
    • AspectJ是一个AOP框架,Spring引入AspectJ作为自身的AOP的开发
  • Spring两套AOP开发方式
    • Spring传统方式动态代理(弃用)
    • Spring基于AspectJ的AOP的开发(使用)

(2)AOP的相关术语

  • 连接点: 一个普通的方法(任何方法都可以被增强,这些方法就称为连接点)
  • 切点: 需要进行增强的方法
  • 通知: 增强的逻辑(方法增强的功能)
  • 切面: 切点+切面
  • 织入: 将通知应用到目标的过程

2.2.1 AspectJ使用(XML)

(1)引入依赖

 <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>

(2)expression:切点表达式

  • public void com.qfdu.dao.impl.UserDaoImpl.findAll()
  • 修饰符 返回值类型 方法名(方法参数)
    • 1.修饰符可以省略
    • 2.返回值类型不能省略 可以使用*来代替
    • 3、包可以使用* 代替
    • 4.方法()不能省略 * .():代表任意方法
    • 5.(…) 方法参数使用…来替代

(3)AOP配置

  • 前置通知:在目标方法执行之前进行增强
  • 后置通知: 在目标方法执行之后进行的操作。
  • 环绕通知: 在目标方法执行前和执行后都要执行(特别
  • 异常通知: 在目标方法执行出现异常的时候,进行增强(捕获到异常后才会进行增强
  • 最终通知: 无论代码是否有异常,总会执行
    • 配置通知时,method表示切面类中的方法,pointcut-ref表示需要增强的方法
      在这里插入图片描述
  • 基于XML的AOP实现事务控制
<!--    AOP(面向切面编程)事务开发-->

<!--    配置目标增强对象-->
    <bean id="accountService" class="com.qfedu.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
<!--    将切面类交给spring管理(事务切面)-->
    <bean id="transactionManager" class="com.qfedu.utils.TransactionManager">
        <property name="connectionUtil" ref="connectionUtil"></property>
    </bean>

<!--    开启aop配置-->
    <aop:config>
<!--        1.定义切点-->
        <aop:pointcut id="transaction" expression="execution(* com.qfedu.service.impl.AccountServiceImpl.transfer(..))"/>
<!--        2.配置切面-->
        <aop:aspect ref="transactionManager">
<!--            前置通知+切点-->
            <aop:before method="begin" pointcut-ref="transaction"></aop:before>
<!--            后置通知+切点-->
            <aop:after-returning method="commit" pointcut-ref="transaction"></aop:after-returning>
<!--            环绕通知+切点-->
<!--            <aop:around method="transactionController" pointcut-ref="transaction"></aop:around>-->
            <!--            异常通知+切点-->
            <aop:after-throwing method="rollback" pointcut-ref="transaction"></aop:after-throwing>
<!--            最终通知+切点-->
            <aop:after method="realease" pointcut-ref="transaction"></aop:after>

        </aop:aspect>
    </aop:config>

(4)环绕通知

  • 切面环绕通知引用方法配置
    在这里插入图片描述
  • 在AOP配置中,配置环绕通知
    在这里插入图片描述

2.2.2 AspectJ使用(注解开发)

(1)在配置文件引入spring对aop注解的支持

<!--开启包扫描-->
<context:component-scan base-package="com.qf"></context:component-scan>

<!--开启spring对aop注解的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

(2)声明切面类 —— @Aspect
在这里插入图片描述

(3)在切面类中配置切点和通知

  • 方式一
    在这里插入图片描述
  • 方式二:
    在这里插入图片描述

(4)存在问题

  • 在使用@Aspect时,由于Spring的版本不同,其通知注解的执行顺寻可能会存在为题
    • @After@AfterReturning@AfterThrowing执行

3. JdbcTemplate

3.1 JdbcTemplate的基本概述

(1)概念:

  • JdbcTemplate是spring框架中提供的一个模板类,是对原生jdbc的简单封装.
  • 模板类: 各种原生操作的封装工具

(2)常见操作的模板类

  • 操作关系型数据库
    • JdbcTemplate
    • HibernateTemplate
  • 操作nosql数据库
    • RedisTemplate
  • 操作消息队列
    • JmsTemplate

(3)作用

  • 它是用和数据库交互的,实现数据表的crud操作

(4)依赖

	<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
    
<!--  tx:事务相关-->    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>

3.2 JdbcTemplate在spring的ioc中配置

  • JdbcTemplate 配置必须指定数据源
  • DriverManagerDataSource 时Spring提供的数据源类,其祖先继承于java.sql.DataSource

(1)XML配置

在这里插入图片描述

(2)注解配置

@PropertySource(value = "classpath:db.properties")
public class JdbcConfig {
//    数据库连接属性
    @Value("${driverClass}")
    private String driver;

    @Value("${jdbcUrl}")
    private String url;

    @Value("${user}")
    private String username;

    @Value("${password}")
    private String password;

//    jdbcTemplate
    @Bean("jdbcTemplate")
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }

//    数据源
    @Bean("dataSource")
    public DataSource getDataSource(){
        DriverManagerDataSource dataSource=new DriverManagerDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setUrl(url);
        return dataSource;
    }
}

(4)JdbcTemplate的CRUD操作

  • execute:可以执行无返回值sql语句,常用于建表、删表的操作
  • query: 用于查询结果集,并自动进行结果集映射封装(可以使用可变参数)
    在这里插入图片描述
    在这里插入图片描述
  • update: 对数据库表进行更新
    在这里插入图片描述

4. Spring的事务管理

4.1 Spring的事务管理的API

(1) PlatformTransactionManager

  • 平台事务管理器:接口,是Spring用于管理事务的真正的对象。
  • 实现类:
    • DataSourceTransactionManager :底层使用JDBC管理事务。
    • HibernateTransactionManager :底层使用Hibernate管理事务。

(2)TransactionDefinition

  • 事务定义:用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读。
  • 获取事务传播行为
    • REQUIRED

​ 如果当前没有事务,就新建一个事务,如果已经存在一个事务,就加入到该事务中(默认值)。

  • SUPPORTS
    支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)。

  • NEVER
    以非事务方式运行,如果当前存在事务,抛出异常。

  • 获取事务是否只读:

    • boolean isReadOnly()
      读写型事务:增加、删除和修改会开启事务。
      只读型事务:执行查询时,也会开启事务。

    建议查询时设置为只读。

4.2 配置编程式事务(了解)

(1)配置平台事务管理器和事务管理模板

  • 平台事务管理器必须指定数据源
    在这里插入图片描述
  • 事务管理模板必须指定事务管理器
    在这里插入图片描述
<!--配置平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--注入数据源-->
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--配置事务管理模板-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <!--注入平台事务管理器-->
    <property name="transactionManager" ref="transactionManager"></property>
</bean>

(2)在业务类中注入事务管理模板

  • 因为事务管理模板才是真正干活对象,真正进行事务的控制
    private AccountDao accountDao;
    private TransactionTemplate transactionTemplate;

    //使用set方法注入
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

在这里插入图片描述
(3)在业务类里面进行事务控制

  • 使用TransactionTemplate提供的execute方法
    • 其参数为抽象类的实现对象TransactionCallbackWithoutResult
    • 实现抽象方法doInTransactionWithoutResult
    • 将业务纯粹的业务逻辑写入doInTransactionWithoutResult方法中,实现事务管理
//    配置编程式事务
    public void transfer(String sourceName, String targetName, Double money) {
            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    //根据名称查询出转账用户
                    Account sourceAccount = accountDao.findAccountByName(sourceName);
                    //根据名称查询转入账用户
                    Account targetAccount = accountDao.findAccountByName(targetName);
                    //转出账户扣钱
                    sourceAccount.setMoney(sourceAccount.getMoney() - money);
                    //转入账户加钱
                    targetAccount.setMoney(targetAccount.getMoney() + money);
                    //更新转出账户
                    accountDao.updateAccount(sourceAccount);
                int i = 1/0;
                    //更新转入账户
                    accountDao.updateAccount(targetAccount);

                }
            });
    }

4.3 配置声明式事务(XML方式)(重点)

在这里插入图片描述

(1)配置事务增强

  • tx:advice需要指定平台事务管理器
<!--    平台事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
  • tx:advice在这里插入图片描述
  • 配置
<!--配置事务增强-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!--配置事务的属性-->
    <tx:attributes>
        <!--name:给哪个业务方法配置事务 propagation:事务的传播行为 REQUIRED默认值-->
        <tx:method name="transfer" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

(2)配置aop,将事务增强和切点连接在一起

<!--    配置aop-->
    <aop:config>
<!--        配置切点-->
        <aop:pointcut id="pointCut" expression="execution(* com.qfedu.service.impl.*.*(..))"/>
<!--        配置织入-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"></aop:advisor>
    </aop:config>

4.4 配置声明式事务(注解方式)(重点)

(1)配置开启注解对事务的支持

  • 方式一: bean.xml中配置(指定平台事务管理器)
<!--    扫描事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
  • 方式二: 在Spring配置文件中添加 @EnableTransactionManagement 注解(扫描事务注解)
    • 示例
      在这里插入图片描述

    • 疑问@EnableTransactionManagement怎么指定平台事务管理器呢?

      • @EnableTransactionManagement会从容器中按照类型获取一个PlatformTransactionManager平台事务管理器
      • 注解源码解释
        在这里插入图片描述

(2)在业务类或业务类中方法上添加注解 @Transactional
在这里插入图片描述

  • @Transactional解析
    • 在@Transactional注解中,可以添加用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读。
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

4.5 编程式事务与声明式事务对比

  • 编程式事务: 通过硬编码的方式实现对事务的管理,存在耦合,此方式不可取
    • 主要通过事务管理器和事务模板,来进行事务管理,执行事务模板的execute方法。存在严重耦合,不采用
  • 声明式事务: 通过AOP的方式实现对事务的管理,不存在耦合性,便于管理(可配置)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/69908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】二叉树的实现OJ练习

文章目录前言(一) 二叉树的接口实现构建二叉树前序遍历中序遍历后序遍历层序遍历二叉树的节点个数二叉树叶子节点个数二叉树第K层节点个数二叉树的高度查找指定节点判断完全二叉树销毁二叉树(二) 二叉树基础OJ练习单值二叉树相同的树另一棵树的子树二叉树的前序遍历二叉树的最大…

[oeasy]python0026_刷新时间_延迟时间_time_sleep_死循环_while_True

刷新时间 回忆上次内容 time 是一个 ​​module​ import 他可以做和时间相关的事情time.time() 得到当前时间戳 time.localtime() 得到本地时间元组local为本地 time.asctime() 得到时间日期字符串asc为ascii 简略的写法为 asc_time time.asctime() 在​​time.asctime()​…

python -- PyQt5(designer)中文详细教程(六)控件1

控件1 控件就像是应⽤这座房⼦的⼀块块砖。PyQt5有很多的控件&#xff0c;⽐如按钮&#xff0c;单选框&#xff0c;滑动条&#xff0c;复选框等 等。在本章&#xff0c;我们将介绍⼀些很有⽤的控 件&#xff1a; QCheckBox &#xff0c; ToggleButton &#xff0c; QSlider &a…

关于JavaScript运算符的学习

关于博主每篇博文的浪漫主义 【“仅此105秒&#xff0c;无法超越的绝美画面!&#xff01;”】 https://www.bilibili.com/video/BV1nW4y1x78x/?share_sourcecopy_web&vd_source385ba0043075be7c24c4aeb4aaa73352 “仅此105秒&#xff0c;无法超越的绝美画面!&#xff01;…

应用案例:有源无源电路协同仿真

01 有源无源电路协同仿真 随着电路系统集成度和信号速率的提高&#xff0c;电路中的电磁场效应越来越明显&#xff0c;单纯使用电路分析方法已不能满足仿真评估精度要求&#xff0c;这种情况下必须对问题进行分解&#xff0c;采用三维电磁场全波方法对信号传播路径上的封装与…

[附源码]计算机毕业设计JAVA在线文献查阅系统

[附源码]计算机毕业设计JAVA在线文献查阅系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

C# 拖放操作

一 拖放操作 拖放操作Drag and Drop是两个窗口之间传递数据的一种手段。 1 拖放操作两部分&#xff1a;拖Drag、放Drop 几个术语&#xff1a; ① 源窗口&#xff1a;发起拖拽StartDrag; ② 目标窗口&#xff1a;接受拖放AcceptDraop; ③ 拖拽物&#xff1a;即传输的数据Dat…

ChatGPT有多厉害,影响到谷歌地位?

AI神器ChatGPT 火了。 能直接生成代码、会自动修复bug、在线问诊、模仿莎士比亚风格写作……各种话题都能hold住&#xff0c;它就是OpenAI刚刚推出的——ChatGPT。 有脑洞大开的网友甚至用它来设计游戏&#xff1a;先用ChatGPT生成游戏设定&#xff0c;再用Midjourney出图&…

外贸小白,一直不出单怎么办?

米贸搜今天&#xff0c;试着给新人一些方法和技巧&#xff0c;让你尽快在公司立足&#xff01; 事实上&#xff0c;规定几个月内下单的公司&#xff0c;往往都是平台有投资&#xff0c;去展会了&#xff0c;有大量营销费用的公司。当然&#xff0c;老板急着收回成本。对于有足…

网络基本概念

文章目录前言网络分层原因网络分层模型各层大致用途主机网络层网际层传输层应用层总结前言 在日常开发中&#xff0c;大家总是会或多或少的遇到一些网络通信的相关代码&#xff0c;如http请求调用。但是我们却不知道&#xff0c;数据是怎么从一台计算机到另一台计算机的&#…

opcj-如何通过一个项目征服Java

Java早已经不是高大山的稀世珍品了&#xff0c;程序员也不再是高科技工作者&#xff0c;而被称为码农 &#xff0c;为什么呢&#xff1f;因为Java后台的很多基础技术都已经固定了&#xff0c;也就是说主要你从头到尾学一遍就能会 &#xff0c;淘宝双十一搞不定&#xff0c;但是…

2022-12-07 小米pro路由(R3G) 刷固件 openwrt

环境准备&#xff1a;路由开启SSH 1.先登录小米开发者平台&#xff0c;解开小米路由的SSH http://www.miwifi.com/miwifi_open.html 2.路由连接电脑&#xff0c;通过SSH可直接登录到小米路由 本教程以R3G 为例 第一步: 刷入 BREED 如何刷入breed 不同设备方法不同,可以直接U…

通俗地讲讲数据降维的原理

什么是数据降维&#xff1f;关于这个问题&#xff0c;很多专家的说法都非常学术&#xff0c;估计很多普通人听不懂。所以&#xff0c;这里用通俗的语言解释一下&#xff0c;希望有助于更多的入门新人理解。 举一个简单的例子&#xff1a;假设一个小学的班级有5个学生&#xff…

Spring Boot 入门到精通(一)

文章目录一、Spring Boot 介绍1. 概念2.maven构建Spring Boot项目3. 自定义banner4. Spring Boot的全局配置文件5. Spring Boot项目的发布方式二、Spring Boot注入方式1. Value方式2. ConfigurationProperties方式3. SpringBoot默认注入方式4. SpringBoot中的默认配置三、Sprin…

Element组件库的用法步骤

Element地址&#xff1a;适用于pc端后台开发 Element - The worlds most popular Vue UI frameworkElement&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.io/#/zh-CN/ 下载 点击 “组件”在安装部分有下载命令&#xf…

东京大学和积水房屋启动生物多样性和健康联合研究

东京大学农业与生命科学研究生院(GSALS)和积水房屋株式会社(Sekisui House, Ltd.)将于2022年12月1日启动关于生物多样性和人类健康的联合研究项目。该项目将调查生物多样性和城市自然环境对人类健康和幸福的益处。这项全球首创的举措将全面调查居民与附近生物多样性丰富的花园环…

Java入门教程(17)——循环语句

文章目录1.while 循环2. do-while 循环3. for 循环我们表白的时候&#xff0c;你可以做我女朋友么&#xff0c;这次拒绝了&#xff0c;下次“你可以做我女朋友么”&#xff0c;直到同意做你女朋友。以后就不会再问了&#xff0c;这就是循环1.while 循环 语法结构&#xff1a; w…

从“挖土豆”到全场景营销,纷享销客CRM如何助力噢易云可持续增长?

近年来&#xff0c;随着云计算技术的发展和普及&#xff0c;桌面云也得到了越来越广泛的应用&#xff0c;尤其是在教育、医疗、金融、能源、连锁等对安全、成本和系统化管控有着强要求的行业中。 根据第三方研究机构的统计&#xff0c;2021年中国桌面云整体解决方案销量达到了…

Java Object类常用API

JavaObject类常用API\huge{Java\space Object类常用API}Java Object类常用API API 首先解释一下什么是APIAPIAPI。 API(ApplicationProgramminginterface)API(Application Programming interface)API(ApplicationProgramminginterface)&#xff1a;应用程序编程接口。 简单来…

docker 查看容器启动命令(已运行的容器)

eg: 1 docker ps 查看正在运行的容器: 通过docker ps命令 该命令主要是为了详细展示查看运行时的command参数 docker ps -a --no-trunc | grep container_name # 通过docker --no-trunc参数来详细展示容器运行命令 通过docker inspect命令 使用docker inspect&#xff0c;但…