springIOC

what is IOC

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)

Dependency Injection

依赖注入

关于什么是依赖

关于注入和查找以及拖拽

为什么要使用spring IOC

spring体系结构----IOC的位置 自己看官网

在日常程序开发过程当中,我们推荐面向抽象编程,面向抽象编程会产生类的依赖,当然如果你够强大可以自己写一个管理的容器,但是既然spring以及实现了,并且spring如此优秀,我们仅仅需要学习spring框架便可。

当我们有了一个管理对象的容器之后,类的产生过程也交给了容器,至于我们自己的app则可以不需要去关系这些对象的产生了。

spring实现IOC的思路和方法

spring实现IOC的思路是提供一些配置信息用来描述类之间的依赖关系,然后由容器去解析这些配置信息,继而维护好对象之间的依赖关系,前提是对象之间的依赖关系必须在类中定义好,比如A.class中有一个B.class的属性,那么我们可以理解为A依赖了B。既然我们在类中已经定义了他们之间的依赖关系那么为什么还需要在配置文件中去描述和定义呢?

spring实现IOC的思路大致可以拆分成3点

1. 应用程序中提供类,提供依赖关系(属性或者构造方法)

2. 把需要交给容器管理的对象通过配置信息告诉容器(xml、annotation,javaconfig)

3. 把各个类之间的依赖关系通过配置信息告诉容器

配置这些信息的方法有三种分别是xml,annotation和javaconfig

维护的过程称为自动注入,自动注入的方法有两种构造方法和setter

自动注入的值可以是对象,数组,map,list和常量比如字符串整形等

spring编程的风格

schemal-based-------xml

annotation-based-----annotation

java-based----java Configuration

注入的两种方法

spring注入详细配置(字符串、数组等)参考文档:
https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-factory-properties-detailed

Constructor-based Dependency Injection

构造方法注入参考文档:
https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-constructor-injection

Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency. Calling a static factory method with specific arguments to construct the bean is nearly equivalent, and this discussion treats arguments to a constructor and to a static factory method similarly. The following example shows a class that can only be dependency-injected with constructor injection:

public class SimpleMovieLister {// the SimpleMovieLister has a dependency on a MovieFinderprivate MovieFinder movieFinder;// a constructor so that the Spring container can inject a MovieFinderpublic SimpleMovieLister(MovieFinder movieFinder) {this.movieFinder = movieFinder;}// business logic that actually uses the injected MovieFinder is omitted...
}

Notice that there is nothing special about this class. It is a POJO that has no dependencies on container specific interfaces, base classes or annotations.

Setter-based Dependency Injection

Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean.

The following example shows a class that can only be dependency-injected by using pure setter injection. This class is conventional Java. It is a POJO that has no dependencies on container specific interfaces, base classes, or annotations.

public class SimpleMovieLister {// the SimpleMovieLister has a dependency on the MovieFinderprivate MovieFinder movieFinder;// a setter method so that the Spring container can inject a MovieFinderpublic void setMovieFinder(MovieFinder movieFinder) {this.movieFinder = movieFinder;}// business logic that actually uses the injected MovieFinder is omitted...
}

自动装配

上面说过,IOC的注入有两个地方需要提供依赖关系,一是类的定义中,二是在spring的配置中需要去描述。自动装配则把第二个取消了,即我们仅仅需要在类中提供依赖,继而把对象交给容器管理即可完成注入。

在实际开发中,描述类之间的依赖关系通常是大篇幅的,如果使用自动装配则省去了很多配置,并且如果对象的依赖发生更新我们可以不需要去更新配置,但是也带来了一定的缺点

自动装配的优点参考文档:

https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-factory-autowire

缺点参考文档:

https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-autowired-exceptions

作为来讲,我觉得以上缺点都不是缺点

自动装配的方法

no
byName
byType
constructor
自动装配的方式参考文档:
https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-factory-autowire
Table 2. Autowiring modes
Mode Explanation

no

(Default) No autowiring. Bean references must be defined by ref elements. Changing the default setting is not recommended for larger deployments, because specifying collaborators explicitly gives greater control and clarity. To some extent, it documents the structure of a system.

byName

Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired. For example, if a bean definition is set to autowire by name and it contains a master property (that is, it has a setMaster(..) method), Spring looks for a bean definition named master and uses it to set the property.

byType

Lets a property be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown, which indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens (the property is not set).

constructor

Analogous to byType but applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised.

spring懒加载

官网已经解释的非常清楚了:

https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-factory-lazy-init

By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the configuration or surrounding environment are discovered immediately, as opposed to hours or even days later. When this behavior is not desirable, you can prevent pre-instantiation of a singleton bean by marking the bean definition as being lazy-initialized. A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.

值得提醒的是,如果你想为所有的对都实现懒加载可以使用官网的配置

In XML, this behavior is controlled by the lazy-init attribute on the <bean/> element, as the following example shows:

<bean id="lazy" class="com.something.ExpensiveToCreateBean" lazy-init="true"/>
<bean name="not.lazy" class="com.something.AnotherBean"/>

You can also control lazy-initialization at the container level by using the default-lazy-init attribute on the <beans/> element, a the following example shows:

<beans default-lazy-init="true"><!-- no beans will be pre-instantiated... -->
</beans>

springbean的作用域

文档参考:
https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-factory-scopes
Table 3. Bean scopes
Scope Description

singleton

(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.

prototype

Scopes a single bean definition to any number of object instances.

request

Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.

session

Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.

application

Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.

websocket

Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

xml定义方式

<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

annotation的定义方式

Singleton Beans with Prototype-bean Dependencies

意思是在Singleton 当中引用了一个Prototype的bean的时候引发的问题
官网引导我们参考https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-factory-method-injection

Method Injection

In most application scenarios, most beans in the container are singletons. When a singleton bean needs to collaborate with another singleton bean or a non-singleton bean needs to collaborate with another non-singleton bean, you typically handle the dependency by defining one bean as a property of the other. A problem arises when the bean lifecycles are different. Suppose singleton bean A needs to use non-singleton (prototype) bean B, perhaps on each method invocation on A. The container creates the singleton bean A only once, and thus only gets one opportunity to set the properties. The container cannot provide bean A with a new instance of bean B every time one is needed.

A solution is to forego some inversion of control. You can make bean A aware of the container by implementing the ApplicationContextAware interface, and by making a getBean("B") call to the container ask for (a typically new) bean B instance every time bean A needs it. The following example shows this approach:

// a class that uses a stateful Command-style class to perform some processing
package fiona.apple;// Spring-API imports
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;public class CommandManager implements ApplicationContextAware {private ApplicationContext applicationContext;public Object process(Map commandState) {// grab a new instance of the appropriate CommandCommand command = createCommand();// set the state on the (hopefully brand new) Command instancecommand.setState(commandState);return command.execute();}protected Command createCommand() {// notice the Spring API dependency!return this.applicationContext.getBean("command", Command.class);}public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}

The preceding is not desirable, because the business code is aware of and coupled to the Spring Framework. Method Injection, a somewhat advanced feature of the Spring IoC container, lets you handle this use case cleanly.

Lookup Method Injection

Lookup method injection is the ability of the container to override methods on container-managed beans and return the lookup result for another named bean in the container. The lookup typically involves a prototype bean, as in the scenario described in the preceding section. The Spring Framework implements this method injection by using bytecode generation from the CGLIB library to dynamically generate a subclass that overrides the method.

  • For this dynamic subclassing to work, the class that the Spring bean container subclasses cannot be final, and the method to be overridden cannot be final, either.

  • Unit-testing a class that has an abstract method requires you to subclass the class yourself and to supply a stub implementation of the abstract method.

  • Concrete methods are also necessary for component scanning, which requires concrete classes to pick up.

  • A further key limitation is that lookup methods do not work with factory methods and in particular not with @Bean methods in configuration classes, since, in that case, the container is not in charge of creating the instance and therefore cannot create a runtime-generated subclass on the fly.

In the case of the CommandManager class in the previous code snippet, the Spring container dynamically overrides the implementation of the createCommand() method. The CommandManager class does not have any Spring dependencies, as the reworked example shows:

package fiona.apple;// no more Spring imports!public abstract class CommandManager {public Object process(Object commandState) {// grab a new instance of the appropriate Command interfaceCommand command = createCommand();// set the state on the (hopefully brand new) Command instancecommand.setState(commandState);return command.execute();}// okay... but where is the implementation of this method?protected abstract Command createCommand();
}

In the client class that contains the method to be injected (the CommandManager in this case), the method to be injected requires a signature of the following form:

<public|protected> [abstract] <return-type> theMethodName(no-arguments);

If the method is abstract, the dynamically-generated subclass implements the method. Otherwise, the dynamically-generated subclass overrides the concrete method defined in the original class. Consider the following example:

<!-- a stateful bean deployed as a prototype (non-singleton) -->
<bean id="myCommand" class="fiona.apple.AsyncCommand" scope="prototype"><!-- inject dependencies here as required -->
</bean><!-- commandProcessor uses statefulCommandHelper -->
<bean id="commandManager" class="fiona.apple.CommandManager"><lookup-method name="createCommand" bean="myCommand"/>
</bean>

The bean identified as commandManager calls its own createCommand() method whenever it needs a new instance of the myCommand bean. You must be careful to deploy the myCommand bean as a prototype if that is actually what is needed. If it is a singleton, the same instance of the myCommand bean is returned each time.

Alternatively, within the annotation-based component model, you can declare a lookup method through the @Lookup annotation, as the following example shows:

public abstract class CommandManager {public Object process(Object commandState) {Command command = createCommand();command.setState(commandState);return command.execute();}@Lookup("myCommand")protected abstract Command createCommand();
}

spring声明周期和回调

参考文档:
https://docs.spring.io/spring-framework/docs/current/spring-framework-
reference/core.html#beans-factory-lifecycle1、Methods annotated with @PostConstruct
2、afterPropertiesSet() as defined by the InitializingBean callback interface
3、A custom configured init() method

Initialization Callbacks

The org.springframework.beans.factory.InitializingBean interface lets a bean perform initialization work after the container has set all necessary properties on the bean. The InitializingBean interface specifies a single method:

void afterPropertiesSet() throws Exception;

We recommend that you do not use the InitializingBean interface, because it unnecessarily couples the code to Spring. Alternatively, we suggest using the @PostConstruct annotation or specifying a POJO initialization method. In the case of XML-based configuration metadata, you can use the init-method attribute to specify the name of the method that has a void no-argument signature. With Java configuration, you can use the initMethod attribute of @Bean. See Receiving Lifecycle Callbacks. Consider the following example:

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {public void init() {// do some initialization work}
}

The preceding example has almost exactly the same effect as the following example (which consists of two listings):

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements InitializingBean {@Overridepublic void afterPropertiesSet() {// do some initialization work}
}

However, the first of the two preceding examples does not couple the code to Spring.

Destruction Callbacks

Implementing the org.springframework.beans.factory.DisposableBean interface lets a bean get a callback when the container that contains it is destroyed. The DisposableBean interface specifies a single method:

void destroy() throws Exception;

We recommend that you do not use the DisposableBean callback interface, because it unnecessarily couples the code to Spring. Alternatively, we suggest using the @PreDestroy annotation or specifying a generic method that is supported by bean definitions. With XML-based configuration metadata, you can use the destroy-method attribute on the <bean/>. With Java configuration, you can use the destroyMethod attribute of @Bean. See Receiving Lifecycle Callbacks. Consider the following definition:

<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
public class ExampleBean {public void cleanup() {// do some destruction work (like releasing pooled connections)}
}

The preceding definition has almost exactly the same effect as the following definition:

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements DisposableBean {@Overridepublic void destroy() {// do some destruction work (like releasing pooled connections)}
}

However, the first of the two preceding definitions does not couple the code to Spring.

Default Initialization and Destroy Methods

When you write initialization and destroy method callbacks that do not use the Spring-specific InitializingBean and DisposableBean callback interfaces, you typically write methods with names such as init()initialize()dispose(), and so on. Ideally, the names of such lifecycle callback methods are standardized across a project so that all developers use the same method names and ensure consistency.

You can configure the Spring container to “look” for named initialization and destroy callback method names on every bean. This means that you, as an application developer, can write your application classes and use an initialization callback called init(), without having to configure an init-method="init" attribute with each bean definition. The Spring IoC container calls that method when the bean is created (and in accordance with the standard lifecycle callback contract described previously). This feature also enforces a consistent naming convention for initialization and destroy method callbacks.

Suppose that your initialization callback methods are named init() and your destroy callback methods are named destroy(). Your class then resembles the class in the following example:

public class DefaultBlogService implements BlogService {private BlogDao blogDao;public void setBlogDao(BlogDao blogDao) {this.blogDao = blogDao;}// this is (unsurprisingly) the initialization callback methodpublic void init() {if (this.blogDao == null) {throw new IllegalStateException("The [blogDao] property must be set.");}}
}

Combining Lifecycle Mechanisms

As of Spring 2.5, you have three options for controlling bean lifecycle behavior:

  • The InitializingBean and DisposableBean callback interfaces

  • Custom init() and destroy() methods

  • The @PostConstruct and @PreDestroy annotations. You can combine these mechanisms to control a given bean.

Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:

  1. Methods annotated with @PostConstruct

  2. afterPropertiesSet() as defined by the InitializingBean callback interface

  3. A custom configured init() method

Destroy methods are called in the same order:

  1. Methods annotated with @PreDestroy

  2. destroy() as defined by the DisposableBean callback interface

  3. A custom configured destroy() method

Fine-tuning Annotation-based Autowiring with Qualifiers

public class MovieRecommender {@Autowired@Qualifier("main")private MovieCatalog movieCatalog;// ...
}
public class MovieRecommender {private MovieCatalog movieCatalog;private CustomerPreferenceDao customerPreferenceDao;@Autowiredpublic void prepare(@Qualifier("main") MovieCatalog movieCatalog,CustomerPreferenceDao customerPreferenceDao) {this.movieCatalog = movieCatalog;this.customerPreferenceDao = customerPreferenceDao;}// ...
}

The following example shows corresponding bean definitions.

<?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><bean class="example.SimpleMovieCatalog"><qualifier value="main"/> <!-- inject any dependencies required by this bean --></bean><bean class="example.SimpleMovieCatalog"><qualifier value="action"/> <!-- inject any dependencies required by this bean --></bean><bean id="movieRecommender" class="example.MovieRecommender"/></beans>

Using Generics as Autowiring Qualifiers

@Configuration
public class MyConfiguration {@Beanpublic StringStore stringStore() {return new StringStore();}@Beanpublic IntegerStore integerStore() {return new IntegerStore();}
}

Injection with @Resource

public class SimpleMovieLister {private MovieFinder movieFinder;@Resource(name="myMovieFinder") public void setMovieFinder(MovieFinder movieFinder) {this.movieFinder = movieFinder;}
}

Using @Value

@Component
public class MovieRecommender {private final String catalog;public MovieRecommender(@Value("${catalog.name}") String catalog) {this.catalog = catalog;}
}

With the following configuration:

@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig { }

And the following application.properties file:

catalog.name=MovieCatalog

Using @PostConstruct and @PreDestroy

public class CachingMovieLister {@PostConstructpublic void populateMovieCache() {// populates the movie cache upon initialization...}@PreDestroypublic void clearMovieCache() {// clears the movie cache upon destruction...}
}

@Component and Further Stereotype Annotations

The @Repository annotation is a marker for any class that fulfills the role or stereotype of a repository (also known as Data Access Object or DAO). Among the uses of this marker is the automatic translation of exceptions, as described in Exception Translation.

Spring provides further stereotype annotations: @Component@Service, and @Controller@Component is a generic stereotype for any Spring-managed component. @Repository@Service, and @Controller are specializations of @Component for more specific use cases (in the persistence, service, and presentation layers, respectively). Therefore, you can annotate your component classes with @Component, but, by annotating them with @Repository@Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts. @Repository@Service, and @Controller can also carry additional semantics in future releases of the Spring Framework. Thus, if you are choosing between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated earlier, @Repository is already supported as a marker for automatic exception translation in your persistence layer.

Using Filters to Customize Scanning

The following table describes the filtering options:

Table 5. Filter Types
Filter Type Example Expression Description

annotation (default)

org.example.SomeAnnotation

An annotation to be present or meta-present at the type level in target components.

assignable

org.example.SomeClass

A class (or interface) that the target components are assignable to (extend or implement).

aspectj

org.example..*Service+

An AspectJ type expression to be matched by the target components.

regex

org\.example\.Default.*

A regex expression to be matched by the target components' class names.

custom

org.example.MyTypeFilter

A custom implementation of the org.springframework.core.type.TypeFilter interface.

The following example shows the configuration ignoring all @Repository annotations and using “stub” repositories instead:

@Configuration
@ComponentScan(basePackages = "org.example",includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),excludeFilters = @Filter(Repository.class))
public class AppConfig {...
}

The following listing shows the equivalent XML:

<beans><context:component-scan base-package="org.example"><context:include-filter type="regex"expression=".*Stub.*Repository"/><context:exclude-filter type="annotation"expression="org.springframework.stereotype.Repository"/></context:component-scan>
</beans>

Generating an Index of Candidate Components

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId><version>5.2.6.RELEASE</version><optional>true</optional></dependency>
</dependencies>

Simple Construction

In much the same way that Spring XML files are used as input when instantiating a ClassPathXmlApplicationContext, you can use @Configuration classes as input when instantiating an AnnotationConfigApplicationContext. This allows for completely XML-free usage of the Spring container, as the following example shows:

public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);MyService myService = ctx.getBean(MyService.class);myService.doStuff();
}

Using @Profile

The @Profile annotation lets you indicate that a component is eligible for registration when one or more specified profiles are active. Using our preceding example, we can rewrite the dataSource configuration as follows:

@Configuration
@Profile("development")
public class StandaloneDataConfig {@Beanpublic DataSource dataSource() {return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("classpath:com/bank/config/sql/schema.sql").addScript("classpath:com/bank/config/sql/test-data.sql").build();}
}
@Configuration
@Profile("production")
public class JndiDataConfig {@Bean(destroyMethod="")public DataSource dataSource() throws Exception {Context ctx = new InitialContext();return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");}
}

模拟spring IOC、源码分析相关推荐

  1. Spring Ioc 源码分析(一)--Spring Ioc容器的加载

    1.目标:熟练使用spring,并分析其源码,了解其中的思想.这篇主要介绍spring ioc 容器的加载 2.前提条件:会使用debug 3.源码分析方法:Intellj idea debug 模式 ...

  2. Spring Ioc源码分析 之 Bean的加载(6):属性填充(populateBean())

    "属性填充",也是在populateBean()方法中. 首先回顾下CreateBean的主流程: 如果是单例模式,从factoryBeanInstanceCache 缓存中获取B ...

  3. Spring Ioc源码分析 之 Bean的加载(4):实例化Bean(createBeanInstance()方法)

    实例化 Bean 在doCreateBean()代码 <2> 处,有一行代码instanceWrapper = createBeanInstance(beanName, mbd, args ...

  4. java获取当前周一_Java互联网架构-Spring IOC源码分析

    欢迎关注头条号:java小马哥 周一至周日下午三点半!精品技术文章准时送上!!! 精品学习资料获取通道,参见文末 源码介绍之前,看几个问题: Bean的承载对象是什么? Bean的定义如何存储的? B ...

  5. Spring Ioc 源码分析(一)- XML 解析

    2019独角兽企业重金招聘Python工程师标准>>> 注 :源码对应版本为 4.2.8.RELEASE 引入Spring依赖的时候,是否发现spring依赖有spring-bean ...

  6. Spring Ioc源码分析 之 Bean的加载(7):初始化

    接着分析doCreateBean()的第6步--初始化 bean 实例对象 首先回顾下CreateBean的主流程: 如果是单例模式,从factoryBeanInstanceCache 缓存中获取Be ...

  7. Spring Ioc源码分析 之 Bean的加载(5):循环依赖处理(populateBean())

    首先回顾下Bean加载的主流程: 1.如果是单例模式,从factoryBeanInstanceCache 缓存中获取BeanWrapper 实例对象并删除缓存 2.调用 createBeanInsta ...

  8. Spring Ioc源码分析系列--容器实例化Bean的四种方法

  9. Spring AOP 源码分析 - 拦截器链的执行过程

    1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...

  10. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

最新文章

  1. 自定义控件:旋转菜单
  2. react16中ref的使用
  3. matlab单元数组和结构,Matlab使用单元数组和结构数组
  4. 信安精品课:2020年软考信息安全工程师备考公开课
  5. java quartz CronScheduleBuilder
  6. python base64加解密
  7. 简明firewalld不断的更新中....
  8. [单片机框架][drivers层][ADC] fuelgauge 软件电量计(二)
  9. 用python 代码写一个表白I love you
  10. word页眉页脚修改
  11. Symantec的SEP服务器(SEPM)从12.1 RU6MP5 升级到14 MP1 操作手册
  12. 2021.3.23 富途牛牛笔试
  13. APP中方法超过64K的解决办法
  14. 《Google Chrome:谷歌浏览器》 --不作恶,但可以恶心你
  15. 探索一下进制转换 (Python 实现源码)
  16. 深信服 EDR终端检测响应平台 0day RCE 漏洞
  17. signature=d208b1bb0cb69ace8714b67c8fb41881,The mechanics of cemented carbonate sands.
  18. 144显示器只有60_windows10系统中144hz显示器刷新率只显示60hz怎么办
  19. 2021年PMP®考试改革
  20. 飞机大战游戏---Pygame

热门文章

  1. springcloud的config
  2. 如何更改tomcat7及以上版本内存设置
  3. 打开AzureRay园子的大门,欢迎大家串门哟~
  4. 【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结...
  5. 一度的让自己变得那么懒惰,不知道后路还会如何
  6. C#生成Excel报表 用MyXls组件生成更完美
  7. mysql中binlog_format模式与配置详解
  8. 使用pip安装BeautifulSoup4模块
  9. 表修改语法之列的增删改
  10. How to log time in Linux? (C Programming)