什么是Bean呢?

  • Swoft中Bean是一个类的对象实例
  • 每个被Swoft管理的PHP对象称之为Bean
  • Swoft提供了一个IoC容器来初始化对象和获取对象,用来解决对象之间的依赖管理。

以前当我们要调用一个类的时候是需要先使用new关键字对类进行实例化后才能使用,现在有了Bean,当Swoft启动的时候就给实例化并一直存在,当你使用时不再需要再去new,这样可以节省资源

以JavaBean为例:JavaBean是一种Java语言编写的可重用组件,为了编写JavaBean类必须是具体的和公共的,并且具有无参构造器。JavaBean通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,并通过setget方法获取。总所周知,属性名符合这种模式,其它Java类可以通过自省(反射)机制发现和操作这些JavaBean的属性。

什么是IoC容器呢?

Swoft为应用提供了一个完整的IoC容器作为依赖管理方案,是Swoft AOP功能、RPC模块等功能的实现基础。

如果对IoC容器不是非常理解的话,请参见《IoC控制反转》。

IoC容器主要解决了三个问题:

  1. 避免手工管理对象之间的依赖嵌套
  2. 对象的依赖关系不再在编译期间确定,提供了运行起改变行为的更多弹性。
  3. 对象可以不再依赖具体实现,而是依赖抽象的接口或是抽象类实现。

什么是Bean容器呢?

容器是一个巨大的工厂,用来存放和管理Bean生命周期。

Bean定义

Bean有两种定义方式:注解、数组配置

  1. 通过数组定义
  2. 通过注解定义:注解定义使用PHP文档注解,在类上做标记,通过解析类注解,实现不同的功能。

例如:中间件的定义中

$ vim /app/Middlewares/ActionTestMiddleware.php
<?php
namespace App\Middlewares;use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Swoft\Bean\Annotation\Bean;
use Swoft\Http\Message\Middleware\MiddlewareInterface;/*** @Bean()* @uses      ActionTestMiddleware*/
class ActionTestMiddleware implements MiddlewareInterface
{public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface{$response = $handler->handle($request);return $response->withAddedHeader('Middleware-Action-Test', 'success');}
}

Bean通过类级别注解@Bean定义,Bean定义后程序可以直接通过App::getBean()获取一个Bean实例。

注解使用

@Bean 注解

命名空间:use Swoft\Bean\Annotation\Bean;

源码分析:

$ vim vendor/swoft/framework/src/Bean/Annotation/Bean.php
<?php
namespace Swoft\Bean\Annotation;
/*** bean注解** @Annotation* @Target("CLASS")* @uses      Bean*/
class Bean
{/*** bean名称* @var string*/private $name = "";/*** bean类型* @var int*/private $scope = Scope::SINGLETON;/*** referenced bean, default is null* @var string*/private $ref = "";/*** Bean constructor.* @param array $values*/public function __construct(array $values){if (isset($values['value'])) {$this->name = $values['value'];}if (isset($values['name'])) {$this->name = $values['name'];}if (isset($values['scope'])) {$this->scope = $values['scope'];}if (isset($values['ref'])) {$this->ref = $values['ref'];}}/*** 获取bean名称* @return string*/public function getName(): string{return $this->name;}/*** 获取bean类型* @return int*/public function getScope(){return $this->scope;}/*** return name of referenced bean* @return string*/public function getRef(): string{return $this->ref;}
}

打开源码,可以看到Bean构造函数可传入一个关联数组的参数。

public function __construct(array $values)
{if (isset($values['value'])) {$this->name = $values['value'];}if (isset($values['name'])) {$this->name = $values['name'];}if (isset($values['scope'])) {$this->scope = $values['scope'];}if (isset($values['ref'])) {$this->ref = $values['ref'];}
}

构造器参数

  • name 定义Bean别名,缺省默认类名。
  • scope 注入Bean类型,默认单例Scope::SINGLETON/Scope::PROTOTYPE
  • ref 指定引用Bean,用于定义在接口上指定使用哪个接口实现。

使用注意

  • @Bean里面只能使用双引号
  • @Bean()是指注入的Bean名称使用包含命名空间的类名。
  • @Bean("userModel")@Bean(name="userModel")含义是一样的
  • @Bean(name="beanName", scope=Scope::SINGLETON) 默认注入的Bean都是单例,使用scope属性设置其类型。

@Inject

命名空间:use Swoft\Bean\Annotation\Inject;
源码分析:

$ vim vendor/swoft/framework/src/Bean/Annotation/Inject.php
<?php
namespace Swoft\Bean\Annotation;
/*** inject注解** @Annotation* @Target({"PROPERTY","METHOD"})** @uses      Inject*/
class Inject
{/*** 注入bean名称* @var string*/private $name = "";/*** Inject constructor.* @param array $values*/public function __construct(array $values){if (isset($values['value'])) {$this->name = $values['value'];}if (isset($values['name'])) {$this->name = $values['name'];}}/*** 获取bean名称* @return string*/public function getName(): string{return $this->name;}
}

构造函数:

  • name 定义属性注入的Bean名称,缺省属性自动为类型名称。

使用注意:

  • @Inject格式与@Bean基本一样,注意通过注解目前不支持构造函数参数注入。
  • @Inject() 默认注入该属性,对应的包含命名空间的类型名Bean。
  • @Inject(name="${logger}")@Inject("${logger}")注入名称为logger的Bean到属性
  • @Inject(name="${config.user.stelin.steln}")注入properties中配置的值,可以层级和直接直接。

使用示例:

/*** 别名注入.* @Inject("httpRouter")* @var \Swoft\Http\Server\Router\HandlerMapping*/
private $router;/*** 别名注入.* @Inject("application")* @var Application*/
private $application;/*** 注入逻辑层* @Inject()* @var IndexLogic*/
private $logic;

操作Bean

App::getBean()提供服务定位器式的依赖管理方式,用于可以通过访问服务定位器获取特定的实例,服务定位器解决了“实例构造,实例间依赖管理,具体实现类选择”的问题,并对用户屏蔽相关细节。

Container->set()方法是App::getBean()底层实际创建Bean的方法,原理是通过反射和各种注解提供的信息和方法构造Bean的一个代理对象。

use Swoft\App;
App::getBean("name");
//例如
$logic = App::getBean(UserLogic::class);
use Swoft\Core\ApplicationContext;
ApplicationContext::getBean('name');
use Swoft\Bean\BeanFactory;
// App/ApplicationContext/BeanFactory都可从容器中得到Bean
BeanFactory::getBean('name');
use Swoft\Bean\BeanFactory;
// hasBean 某个bean是否存在
BeanFactory::hasBean("name");

Swoft 2.x 详解Bean相关推荐

  1. Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!

    点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...

  2. Spring 详解Bean的后置处理器

    Bean的后置处理器详解: Spring当中的后置处理器是Spring体用的一个扩展点,开发者只要去实现,Spring当中的BeanPostProcessor接口,那么就能插手SpringBean实例 ...

  3. 详解Bean Validation

    理性阅读,欢迎探讨 1. Bean Validation是什么? Bean Validation 是一个数据验证规范,属于Java EE 6的子规范,详情参考维基百科,这里不做赘述. 既然是规范,那么 ...

  4. Spring核心组件详解(Bean、Context、Core)

    上篇文章介绍了Spring的有三个核心组件,它们为什么是Spring的核心组件,它们之间啥关系,都代表了啥角色. 下面将详细介绍每个组件内部类的层次关系,以及它们在运行时的时序顺序.我们在使用 Spr ...

  5. Spring中bean的执行初始化和销毁方法的4种方式详解

    一.引入 在java的实际开发过程中,我们可能需要在spring实例化一个bean的过程中,使用到初始化一个对象(bean)后立即初始化(加载)一些数据,或者在销毁一个对象之前进行执行一些事情等等. ...

  6. theos linux环境,theos安装详解

    Go语言异步服务器框架原理和实现 Go语言类库中,有两个官方的服务器框架,一个HTTP,一个是RPC.使用这个两个框架,已经能解决大部分的问题,但是,也有一些需求,这些框架是不够的,这篇文章,我们先分 ...

  7. Spring——三级缓存解决循环依赖详解

    三级缓存解决循环依赖详解 一.什么是三级缓存 二.三级缓存详解 Bean实例化前 属性赋值/注入前 初始化后 总结 三.怎么解决的循环依赖 四.不用三级缓存不行吗 五.总结 一.什么是三级缓存 就是在 ...

  8. Springboot@Configuration和@Bean详解

    Springboot@Configuration和@Bean详解 一.@Configuration @Target({ElementType.TYPE}) @Retention(RetentionPo ...

  9. java spring bean配置文件_Spring基于xml文件配置Bean过程详解

    这篇文章主要介绍了spring基于xml文件配置Bean过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 通过全类名来配置: class:be ...

最新文章

  1. 不是广告--如何学Java,我说点不太一样的学习方式
  2. NOIP2008 双栈排序
  3. java main方法调用非静态方法_java中main函数怎么调用外部非static方法
  4. linux运维(五)
  5. 无线通信技术协议-Zigbee 3.0
  6. 数据处理——数据编码
  7. Content Provider的启动过程
  8. 如何利用MongoDB打造TOP榜小程序
  9. jmeter简单使用教程
  10. T430s BIOS白名单破解
  11. linux中原子量的学习和理解
  12. 怎么看待小公司的规章制度?
  13. 自定义关机计算机,win7自定义定时关机设置方法是什么
  14. 论文:CenterNet: Keypoint Triplets for Object Detection 阅读笔记
  15. 课堂派考试可以切屏吗_雨课堂考试可以切屏吗?能切出去搜答案吗
  16. Orion2 CDM 操作系统-操作部分20211206
  17. 【设计模式03】 建造者模式
  18. 人类会被人工智能打败吗?
  19. 「 C/C++疑难杂症 」warning: ISO C++ forbids converting a string constant to ‘CHAR*’ {aka ‘char*’} [-Wwrite
  20. springboot返回时间有错解决方案

热门文章

  1. ubuntu:docker常用命令
  2. 程序员免费学英语,省几万培训费!
  3. java编程软件教程_Java编程软件图文版教程,快来看看吧
  4. keil的jlink重新选择芯片识别
  5. 我们究竟为什么上大学
  6. 闪耀世界人工智能大会背后,AI头雁百度已成智能经济强力引擎
  7. HBase如何实现模糊查询?
  8. idw matlab 程序_matlab小波变换程序
  9. 数字二阶低通滤波器公式推导及代码实现
  10. python 爬取抖音个人分享页面信息保存到数据库