El marco de desarrollo integral Go-Spring lanzó la versión v1.1.2

Solo dos semanas después del último lanzamiento, Go-Spring, el marco de desarrollo integral para el backend de Go, ha lanzado una nueva versión que implementa dos características muy importantes: configuración dinámica y uso compartido de beans.

Configuración dinámica

A veces queremos poder modificar la configuración del programa y cambiar el comportamiento del programa sin tiempo de inactividad, la llamada "configuración dinámica". Go-Spring implementa el mismo uso que las propiedades ordinarias mediante el uso de tipos de datos especiales. Admite valores predeterminados y verificación de tipos, al tiempo que garantiza la seguridad de la concurrencia de datos, que es muy simple y potente.

type DynamicConfig struct {
	Int   dync.Int64   `value:"${int:=3}" validate:"$<6"`
	Float dync.Float64 `value:"${float:=1.2}"`
	Map   dync.Ref     `value:"${map:=}"`
	Slice dync.Ref     `value:"${slice:=}"`
	Event dync.Event   `value:"${event}"`
}

type DynamicConfigWrapper struct {
	Wrapper DynamicConfig `value:"${wrapper}"`
}

func TestDynamic(t *testing.T) {

	var cfg *DynamicConfig
	wrapper := new(DynamicConfigWrapper)

	c := gs.New()
	c.Provide(func() *DynamicConfig {
		config := new(DynamicConfig)
		config.Int.OnValidate(func(v int64) error {
			if v < 3 {
				return errors.New("should greeter than 3")
			}
			return nil
		})
		config.Slice.Init(make([]string, 0))
		config.Map.Init(make(map[string]string))
		config.Event.OnEvent(func(prop *conf.Properties) error {
			fmt.Println("event fired.")
			return nil
		})
		return config
	}).Init(func(config *DynamicConfig) {
		cfg = config
	})
	c.Object(wrapper).Init(func(p *DynamicConfigWrapper) {
		p.Wrapper.Slice.Init(make([]string, 0))
		p.Wrapper.Map.Init(make(map[string]string))
		p.Wrapper.Event.OnEvent(func(prop *conf.Properties) error {
			fmt.Println("event fired.")
			return nil
		})
	})
	err := c.Refresh()
	assert.Nil(t, err)

	{
		b, _ := json.Marshal(cfg)
		assert.Equal(t, string(b), `{"Int":3,"Float":1.2,"Map":{},"Slice":[],"Event":{}}`)
		b, _ = json.Marshal(wrapper)
		assert.Equal(t, string(b), `{"Wrapper":{"Int":3,"Float":1.2,"Map":{},"Slice":[],"Event":{}}}`)
	}

	{
		p := conf.New()
		p.Set("int", 4)
		p.Set("float", 2.3)
		p.Set("map.a", 1)
		p.Set("map.b", 2)
		p.Set("slice[0]", 3)
		p.Set("slice[1]", 4)
		p.Set("wrapper.int", 3)
		p.Set("wrapper.float", 1.5)
		p.Set("wrapper.map.a", 9)
		p.Set("wrapper.map.b", 8)
		p.Set("wrapper.slice[0]", 4)
		p.Set("wrapper.slice[1]", 6)
		c.Properties().Refresh(p)
	}

	{
		b, _ := json.Marshal(cfg)
		assert.Equal(t, string(b), `{"Int":4,"Float":2.3,"Map":{"a":"1","b":"2"},"Slice":["3","4"],"Event":{}}`)
		b, _ = json.Marshal(wrapper)
		assert.Equal(t, string(b), `{"Wrapper":{"Int":3,"Float":1.5,"Map":{"a":"9","b":"8"},"Slice":["4","6"],"Event":{}}}`)
	}
}

compartir frijol

Java Spring Redis utiliza una función muy especial en la página principal, que puede inyectar el valor de campo de un bean en otro objeto, que parece que el bean se comparte. Ahora Go-Spring también puede admitir dicho uso.

type runner struct {
	Client *redis.Client           `autowire:""`
	StrOps *redis.StringOperations `autowire:"RedisClient"`
}

func (r *runner) Run(ctx gs.Context) {

	_, err := r.Client.OpsForString().Get(ctx.Context(), "nonexisting")
	if !redis.IsErrNil(err) {
		panic(errors.New("should be redis.ErrNil"))
	}

	_, err = r.Client.OpsForString().Set(ctx.Context(), "mykey", "Hello")
	util.Panic(err).When(err != nil)

	v, err := r.Client.OpsForString().Get(ctx.Context(), "mykey")
	util.Panic(err).When(err != nil)

	if v != "Hello" {
		panic(errors.New("should be \"Hello\""))
	}

	v, err = r.StrOps.Get(ctx.Context(), "mykey")
	util.Panic(err).When(err != nil)

	if v != "Hello" {
		panic(errors.New("should be \"Hello\""))
	}

	go gs.ShutDown()
}

func main() {
	gs.Object(&runner{}).Export((*gs.AppRunner)(nil))
	fmt.Printf("program exited %v\n", gs.Web(false).Run())
}

Supongo que te gusta

Origin www.oschina.net/news/210115
Recomendado
Clasificación