首页 > 其他分享 >SpringIOC和AOP机制的学习

SpringIOC和AOP机制的学习

时间:2023-12-17 23:56:11浏览次数:46  
标签:SpringIOC 创建 对象 Spring bean AOP 注解 机制 public

SpringIOC和AOP机制的学习

5、HelloSpring_哔哩哔哩_bilibili

springIOC依赖

code-block

直接导入mvc依赖也可以

          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.7</version>
        </dependency>

image-20230530170157131

SpringIOC理论推导

原来业务实现步骤:

  1. Dao实现Mapper接口

  2. Dao实体类

  3. Service业务接口

  4. serviceImp业务实现类

存在的问题

在我们的业务中,用户的需求可能会影响我们原代码。

img

本质上解决了问题,程序员不用再去管理对象的创建

系统的耦合性大大降低,可以更专注在业务的实现上

这是IoC(控制反转)的原型,反转(理解):主动权交给了用户

//在Service层的实现类(UserServiceImpl)增加一个Set()方法
//利用set动态实现值的注入!
private UserDao userDao;
public void setUserDao(UserDao userDao){
    this.userDao = userDao;
}
  • 之前,程序是主动创建对象!控制权在程序猿手上,已经在代码中写死了的 比如一个类的对象=new 类()

  • 使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象!(主动权在客户手上

  • img

IoC本质

控制反转IoC是一种设计思想,Dl(依赖注入)是实现IoC的一种方法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象的依赖关系完全硬编码在程序中,对象的创建由程序控制,控制反转后将对象的创建转移给第三方。

img

控制反转是一种通过描述(XML或者注解)并通过第三方生产或获取特定对象的方式,在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入DI

applicationcontext.xml配置

<?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">

    <!--在Spring中创建对象,在Spring这些都称为bean
        类型 变量名 = new 类型();
        Holle holle = new Holle();

        bean = 对象(holle)
        id = 变量名(holle)
        class = new的对象(new Holle();)
        property 相当于给对象中的属性设值,让str="Spring"
    -->

    <!--使用Spring来创建,在Spring这些都称之为bean-->
    <bean id="hello" class="com.hy.pojo.Hello">
        <property name="str" value="Spring"></property>
        <!--ref是引用容器中创建好的对象-->
         <!--value是具体的值,是基本数据类型-->
    </bean>

</beans>

类的实例化的核心是用到了反射技术,所以类要有无参构造方法 invoke()实现

属性实例化的核心用set注入,所以必须要有下面的set()方法

  • Hello对象是由Spring创建得

  • Hello对象得属性是由Spring设置得

这个过程就叫做控制反转

控制:谁来控制对象得创建,传统应用程序的对象由程序本身创建,使用Spring之后对象由Spring创建。

反转:程序本身不创建对象,而变成被动得接受对象

依赖注入:就是利用set方法进行注入

IoC是一种编程思想,由主动编程编程被动接受

可以通过 newClassPathXmlApplicationContext去浏览底层源码

IoC创建对象的方式

默认方式:通过无参构造

类的实例化的核心是用到了反射技术,所以类要有无参构造方法 invoke()实现

通过有参构造

下标赋值

index指的是有参构造中参数的下标,下标从0开始

<bean id="user" class="pojo.User">
    <constructor-arg index="0" value="chen"/>
</bean>

类型赋值(不建议使用)当出现两个类型一样的就不好配置了

<bean id="user" class="pojo.User">
    <constructor-arg type="java.lang.String" value="kuang"/>
</bean>

直接通过参数名(掌握)

<!-- 比如参数名是name,则有name="具体值" -->
<bean id="user" class="pojo.User">
    <constructor-arg name="name" value="kuang"></constructor-arg>
</bean>
<!--官方的写法-->
<bean id="user" class="pojo.User">
        <constructor-arg ref="beanone"></constructor-arg>
</bean>
<bean id="beanone" class="pojo.XXX"></bean>

总结:在配置文件加载的时候,容器中管理的对象就已经被初始化了!

Spring比作婚庆公司,在你去访问的时候,里面的"对象"就已经被创建好了,当你准备选择谁的时候相当于getBean()操作获取对象。同时多人访问时,也内存中也只是有一个对象。

在注册bean之后就对象的初始化了类似 new 类名()

Spring配置说明

别名:

<alias name="bean的id名" alias="自己起一个名字">
两个名字使用getBean()都可以实例化对象
</alias>

Bean配置:

<!--id:bean的唯一标识符,也就是相当于我们学的对象名
class:bean对象所对应的会限定名:包名+类型
name:也是别名,而且name可以同时取多个别名 -->
<bean id="user" class="pojo.User" name="u1 u2,u3;u4">
    <property name="name" value="chen"/>
</bean>
<!-- 使用时
    User user2 = (User) context.getBean("u1");
-->

import配置

应用场景:当多个人去开发时,每个人都是用不同的bean容器,当需要合并是可以选择一个主要的bean容器,然后导入,当让也可以是classpathxmlApplicationcontext()扫描多个.xml文件

比如

张三(bean1)

李四(bean2)

王五(bean3)

在applicationContext.xml

<import resource="beans.xm1"/>
<import resource="beans2.xml"/>
<import resource="beans3.xm1"/>

使用的时候,直接使用总的配置就可以了

当这些bean中出现重名的情况时Spring按照在总的XML中的导入顺序来进行创建,后导入的会重写先导入的,最终实例化的对象会是后导入XML中的那个\

DI依赖注入环境

构造器注入

set方法注入

依赖注入:set注入!

  • 依赖:bean对象的创建依赖于容器

  • 注入:bean对象中的所有属性,由容器来注入

  • Student类使用bean来将下面的属性全部进行初始化

import jdk.nashorn.internal.objects.annotations.Property;
import lombok.Data;

import java.util.List;
import java.util.Map;
@Data
public class Student {
     private String name;
     private List<String> list;
     private Map<String,String> map;
     private Property property;
     private Address address;
}
<bean id="address" class="com.zhoulei.Dom.Address">
        <property name="city" value="常德"></property>
        <property name="rural" value="澧县"></property>
    </bean>
    <bean id="student" class="com.zhoulei.Dom.Student">
        <property name="name" value="周磊"></property>
        <property name="address" ref="address"></property>
        <!--数组注入-->
        <property name="str">
            <array>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </array>
        </property>
        <!--list注入-->
        <property name="list" >
            <list>
                <value>1</value>
            </list>
        </property>
        <!--map注入-->
        <property name="map">
            <map>
                <entry key="a" value="1"></entry>
            </map>
        </property>
        <!--property文件注入-->
        <property name="property">
            <props>
                <prop key="crod">aaaa</prop>
            </props>
        </property>
    </bean>

注意:当什么属性的值为null时,需要使用

拓展注入(C或P命名空间)

pojo增加User类

package pojo;
@Data
public class User {
    private String name;
    private int id;
    public User() {
    }
}

注意: beans 里面加上这下面两行

使用p和c命名空间需要导入XML约束

xmlns:p=“http://www.springframework.org/schema/p”

xmlns:c=“http://www.springframework.org/schema/c”

?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:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--p命名空间注入/set注入,可以直接注入属性的值-》property-->
    <bean id="user" class="pojo.User" p:name="cxk" p:id="20" >
    </bean>

    <!--c命名空间,通过构造器注入,需要写入有参和无参构造方法-》construct-args-->
    <bean id="user2" class="pojo.User" c:name="cbh" c:id="22"></bean>
</beans>

Bean作用域(scope)

<!--单例模式默认所得到的对象都是一个-->
<bean id="user2" class="pojo.User" c:name="cxk" c:age="19" scope="singleton"></bean>
<!--原型模式,每次创建getbean之后都是独立的对象-->
<bean id="user2" class="pojo.User" c:name="cxk" c:age="19" scope="prototype"></bean>

作用域

singleTon:单例 每次创建对象都一样

prototype:多例每次创建的对象都不一样

request:创建的对象在Web一次请求中有效,针对Web项目有效

Session:创建的对象在一次会话中有效 Web

GlobalSession:创建的对象在分布式项目中的全局session中有效

Application:创建的对象在整个项目周期内有效

Bean的自动装配

  • 自动装配是Spring满足bean依赖一种方式

  • Spring会在上下文中自动寻找,并自动给bean装配属性

Spring有三种装配方式

  • 手动XML显示装配

  • javaconfig装配

  • 隐式bean自动装配

自动配置属性:

  • autowrire="byname" byname:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid

缺点也很明显当名字出现不相同的时候就无法实现自动装配了,不够灵活

<bean id="dog" class="com.zhoulei.Dom.dog"> </bean>
  <bean id="cat" class="com.zhoulei.Dom.cat"> </bean>
    <bean id="student" class="com.zhoulei.Dom.Student" autowire="byName">

    </bean>
  • autowrite="bytype" bytype:会自动在容器上下文中查找,和自己对象属性类型相同的beanid;

缺点当出现了多个属性一样的bean之后会直接报错。

<bean id="dog" class="com.zhoulei.Dom.dog"> </bean>
  <bean id="cat" class="com.zhoulei.Dom.cat"> </bean>
    <bean id="student" class="com.zhoulei.Dom.Student" autowire="bytype">

    </bean>

注解实现自动装配

jdk1.5支持注解开发,Spring是jdk2.5

使用注解开发前提:

  • 导入约束

    code-block
    

xmlns:context="http://www.springframework.org/schema/context"

- 导入注解支持

​```xml
<context:annotation-config/>

@Autowrited

@Autowrited会更根据类型和名字区寻找bean默认先通过类型bytype如果找不到bean的话就会按照byname来寻找

注解的作用域

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})

可以在属性上面和set上面。

使用Autowrited注解可以不需要set方法

在bean环境复杂的情况下不如同一个类型的bean有多个并且不存在一个beanid和类中的属性名称一样的情况我们可以使用@Qualifier注解来标识我们想指定的bean

@Data
public class Student {
      @Autowired
      @Qualifier("dog1")
      private dog dog;
      private cat cat;
}

@Resource注解也具有自动装配的效果是Java自己支持的自动装配注解效果和Autowrited差不多默认是使用byname然后使用bytype

Spring注解开发

  • 需要导入aop依赖

  • 在applicationContent.xml文件中使用包扫描

    code-block
    

<context:component-scan base-package="com.zhoulei">/context:component-scan

### @Component

可以将注解的类放入到bean仓库中管理

​```java
@Component
@Data
public class Student {
    @Value("dog")
    private String dog;
}

衍生的注解

@Component有几个衍生注解,会按照Web开发中,mvc架构中分层。

  • dao (@Repository)

  • service(@Service)

  • controller(@Controller)

这四个注解的功能是一样的,都是代表将某个类注册到容器中

使用Java来配置XML文件

package com.zhoulei.config;

import com.zhoulei.pojo.user;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration//标明这个类是一个Spring的配置类相当与beans标签,这个标签内部也使用Component表名这个注解的类也会交给spring来管理
@ComponentScan("com.zhoulei.pojo")//配置包扫描,使在该包下面的Component以及衍生注解生效,将注解的类放入到bean中由Spring管理
@Import(Myconfig2.class)//导入其他的配置文件
public class Myconfig {
    @Bean
    //在方法上使用这个注解以后相当与xml文件中的bean
    //其中方法名称相当于是id名称
    //返回值相当于是class:后面的值
    //思考使用这方式来怕配置bean如何来赋值呢?
    //简单属性可以使用注解@Value可以赋值
    public user getUser(){
        return new user();
    }
}
public class Springtest {
    @Test
    public void test(){
        ApplicationContext app = new AnnotationConfigApplicationContext(Myconfig.class);
        user user = app.getBean("getUser", user.class);
        System.out.println(user.getName());
    }
}

没有注意到这个细节

会创建两个相同对象问题的说明:王富贵 (lmlx66.top)

学长大佬总结 - -> @Bean是相当于< bean>标签创建的对象,而我们之前学的@Component是通过Spring自动创建的这个被注解声明的对象,所以这里相当于有两个User对象被创建了。一个是bean标签创建的(@Bean),一个是通过扫描然后使用@Component,Spring自动创建的User对象,所以这里去掉@Bean这些东西,然后开启扫描。之后在User头上用@Component即可达到Spring自动创建User对象了

代理模式

什么要学习静态代理模式?

这个就是AOP的底层逻辑

静态代理

主要角色分为:

  • 真实对象,拥有资源可以分配的对象比如房租

  • 抽象角色,一般是接口用来处理动作的。

  • 代理对象,帮助真实对象处理一些公共的繁琐的动作比如中介需要接待客户以及合同

  • 客户,需要得到自己资源的对象。

好处

可以方便拓展公共动作。分工明确

缺点

增加了代码量

AOP切面逻辑

image-20230607150356008

动态代理

  • 动态代理和静态代理角色一样

  • 动态代理使用动态生成。

  • 动态代理主要分为两大类:基于接口的动态代理,基于类的动态代理

    • 基于接口--jdk动态代理

    • 基于类:cglib

    • Java字节码

    需要提前了解这两个类 proxy :代理 ,invocationHandler :调用处理程序

package com.zhoulei.dome03;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Proxyinvocation implements InvocationHandler {
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }

    // Foo f =(Foo) Proxy.newProxyInstance(Foo. Class.GetClassLoader(),
    // new Class<?>[] { Foo.Class },
    // handler);
    // 生成代理类
    public Object getProxy(){
        return  Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }

    //处理代理实例并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(rent, args);
        return result;
    }
}

Spring实现AOP

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

Spring学习

1、在Sping模块使用AOP需要在ApplicationContext.XML需要配置包扫描

<!--包扫描-->
<context:component-scan base-package="com.www"></context:component-scan>
<!--aop扫描接口-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2、使用AOP注解开发时首先需要自己定义以Annotion注解对象

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface invokeLog {
//invokeLog是自己定义的注解对象,主要功能是在需要增强的方法上面加上相应的
//注解。
}

3、接下来建立切面类,主要包括可以使用切面表达式(execution)或者使用@annotion注解,使用@Around("pt()")环绕注解,并且该类还要使用@Component加载该类的Bean对象@Aspect是该类变成一个切面类

@Component
@Aspect
public class Cut {
    @Pointcut("@annotation(invokeLog)")
    public void pint(){
    }
    @Around("pint()")
    public Object printf(ProceedingJoinPoint pjp){
        Object[] args = pjp.getArgs(); //获取目标方法的参数
        String str=(String)(args[0]);//将获取到先参数强转换成为String类型
        System.out.println(str);
        MethodSignature ms = (MethodSignature) pjp.getSignature();
        String name = ms.getName();//返回目标方法的名称
        String type = ms.getDeclaringTypeName();//返回目标方法的所在的类名
        System.out.println(name);
        System.out.println(type);
        Object ret=null;
        try {
            ret = pjp.proceed();//执行目标方法
            System.out.println(ret.getClass().getName());//函数的返回值类型
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("方法被执行,生效");
        return ret;
    }

}

Spring-mybatis

导入MyBatis

<!--//mybatis整合Spring的整合包-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.4</version>
</dependency>
<!--Spring操作数据库-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.1.9.RELEASE</version>
</dependency>

复制学长的笔记王富贵 (lmlx66.top)

<?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:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--DataSource:使用Spring的数帮源替换Mybatis的配置 其他数据源:c3p0、dbcp、druid 
        这使用Spring提供的JDBC: org.springframework.jdbc.datasource 
        使用alibabaDruid连接池
扫描jdbc.proprtties文件,配置jdbc的基础属性
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
配置DruidDataSource属性建立连接池
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
    <property name="driverClassName" value="${jdbc.driver}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="password" value="${jdbc.password}"></property>
    <property name="username" value="${jdbc.username}"></property>
</bean>
-->
    <!--data source -->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"
            value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource" />
        <!--绑定 mybatis 配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--这步也可以省略掉,在mybatis-config.xml文件中配置或者使用包扫描(个人图方便)
         或者
扫描
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" id="configurer">
    <property name="basePackage" value="com.zhoulei"></property>
</bean>
-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <!-- sqlSessionTemplate 就是之前使用的:sqlsession -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 只能使用构造器注入sqlSessionFactory 原因:它没有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

</beans>

Spring声明式事务

jar spring-tx 在JDBC中以及依赖了

声明式事务XML配置

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
 <!--结合aop实现事务织入-->
    <!--配置事务的通知类-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--给哪些方法配置事务-->
        <!--新东西:配置事务的传播特性 propagation-->
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="update" propagation="REQUIRED"/>
            <tx:method name="query" read-only="true"/>
            <!-- *号包含上面4个方法:
            <tx:method name="*" propagation="REQUIRED"/> -->
        </tx:attributes>
    </tx:advice>
    <!--配置事务切入-->
    <aop:config>
        <aop:pointcut id="txpointcut" expression="execution(* mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txpointcut"/>
    </aop:config>

声明式事务注解配置

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="txManager"/>

在想要实现事务的方法和类上面使用

@Transactional//设置事务回滚异常(class) //开启事务

@Transactional作用域

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)

标签:SpringIOC,创建,对象,Spring,bean,AOP,注解,机制,public
From: https://www.cnblogs.com/wzl66/p/17910122.html

相关文章

  • 安卓之同步机制优劣分析
    文章摘要  随着移动设备的普及,安卓操作系统已成为全球使用最广泛的移动操作系统之一。在安卓开发中,多线程编程是不可避免的,而同步机制则是确保多线程正确、高效运行的关键。本文将深入分析安卓中几种常见的同步机制,包括它们的优缺点,并提供相应的代码示例。正文synchronized......
  • C++ AOP 编程介绍
    AOP(Aspect-OrientedProgramming)是一种编程范式,将程序的非核心逻辑都“横切”处理,实现非核心逻辑与核心逻辑的分离【1】在日常工作中,会遇到一类需求:统计业务处理的耗时或者加锁,业务函数可以动态替换而非侵入式修改业务函数;简单粗暴的方法是:RetProcess(...)//业务函数{......
  • AOP
    2023-12-1616:42:561.AOP1.1作用保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能。1.2注解声明切入点  ①   使用execution指示器选择方法,方法表达式以*号开始,标识我们不关心方法的返回值类型。然后我们指定了全限定类名和方法名。对于方法......
  • .NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题
    背景随着公司微信相关业务场景的不断拓展,从最初的一个微信移动应用、然后发展成微信公众号应用、然后又有了微信小程序应用。但是随着应用的拓展,如何保证相同用户的微信用户在不同应用中登录的同一个账号呢?今天的主题就来了.NET微信网页开发之通过UnionID机制解决多应用用户帐号......
  • LTE的处理流程和机制
    LTE的处理流程和机制来源 https://zhuanlan.zhihu.com/p/645672554参考目录 https://zhuanlan.zhihu.com/p/658378789 一.UE工作状态在通信过程中,我们的手机也就是UE(UserEquipment)的处理可以分为以下三种情况,开机过程、待机状态和联机状态,每种状态下完成的任务如下所示:......
  • 注意力机制
    注意力机制一、注意力机制人可以通过眼睛看到各种各样的事物,感知世界上的大量信息,但可以让自己免受海量信息的干扰,可以选择重要信息而忽视不重要信息。例如一张图片,我们会把下意识把注意力集中在主体身上,而非背景。同样,希望网络也具有这种能力,引入注意力机制是对输入进行加权......
  • Spring系列:基于Spring-AOP和Spring-Aspects实现AOP切面编程
    目录一、概念及相关术语概念相关术语①横切关注点②通知(增强)③切面④目标⑤代理⑥连接点⑦切入点作用二、基于注解的AOP技术说明准备工作创建切面类并配置各种通知切入点表达式语法重用切入点表达式获取通知的相关信息环绕通知切面的优先级三、基于XML的AOP准备工作实现一、概念......
  • redis 使用主从机制复制数据
    查看主从情况127.0.0.1:6379>inforeplication#Replicationrole:masterconnected_slaves:0master_repl_offset:12539repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0建立主从(在备机操作)注意,如果让有数据的......
  • UE4 World Composition机制
    世界场景构成(WorldComposition)属于关卡流送的一种,旨在简化大型世界场景的子关卡管理,通过关卡流送的方式读取地块信息,减轻运行压力,从而实现大型世界场景的运行。与传统关卡管理方式的区别:无需手动将关卡添加到场景中,只需将关卡放置到主地图所在的目录下(可建子目录)。 主关卡(Pe......
  • net core 异步超时取消机制
    方法一:利用Task.WhenAnynamespaceConsoleApp1{internalclassProgram{staticvoidMain(string[]args){Console.WriteLine("Hello,World!");CancellationTokenSourcects=newCancellationTokenSource......