通过注解和反射实现一个简单的@Value注解

通过注解和反射实现一个简单的@Value注解,第1张

Java注解(Annotation)就是一种java标注,并且能够携带数据, 是在JDK50被引入的。

Java的注解可以标注Java语言中的类、变量、方法、参数、包等等。

值得注意的是: 上面所说的Java注解只是一种标注,所以注解需要配合反射来使用才能发挥出强大作用。

注解的成员变量只支持 八种基本数据类型(byte、short、int、long、float、double、char、boolean)、String、Class、Enum、Annotation

还有的就是,所有的注解都是Annotation接口的实现类,可以把Annotation接口看成是所有注解的超类

上面就是定义了一个可以标注在类或者注解以及方法上的,保留到运行期的注解。 但是也仅仅是定义了一个注解而已,一个注解要发挥它自己的作用,还需要反射的配合。

反射是java中的一种机制,通过这种机制我们能够在运行时获取到一个类的一切信息(继承的类、实现的接口、属性、方法等), 以及注解信息和注解所携带的数据

通过获取到的类信息,我们可以构造一个新的对象、获取到某个对象的属性值、执行某个对象的方法等。

定义value注解

定义pojo User类

测试并使用注解

//@PropertySource:读取属性文件@PropertySource(value={"classpath:conf/properties"})

@Configurationpublic class ConfigOfLifeCycle {

@Bean public Student student(){ return new Student();

}

}

@Configuration , @ComponentScan ,

@Component , @Controller , @Service , @Repository , @RestController ,

@Bean , @Scope ,

@Autowired , @Resource ,

@Qualifier ,

@PostConstruct , @PreDestory ,

@RequestMapping , @GetMapping , @PostMapping , @PutMapping , @DeleteMapping , @PatchMapping ,

@RequestBody , @Validated , @Valid , @RequestParam , @PathVariable ,

@ModelAttribute

作用:用 @Configuration 标注的类就相当于 xml 中的<beans> </beans>

注意:

作用:扫描指定包下的组件,意思就是把指定包下有 @Component 或 @Controller 或 @Service 或 @Repository 注解标注的类,注入到 spring 容器中。

使用示例:

Test 类

Apple 类

作用:返回 Bean 实例,相当于<beans><bean /></beans>中的<bean />部分。

属性:

value

name:默认为方法名,等同于 value,相当于 bean 的名称,二者不能同时使用。

autowire : 表示该 bean 自动装配的类型,不推荐使用。

参数:AutowireNO(默认),AutowireBY_NAME,AutowireBY_TYPE

initMethod:对象初始化调用方法。

destroyMethod:对象销毁调用方法。

使用示例

Test 类

Banana 类

作用:将当前类交给 spring bean 工厂管理。

属性:value 不写,默认 value 值为类名(类名首字母小写)。

使用示例:

Fruit 接口

Apple 类(要交给 bean 工厂管理的类)

Test 类

@Controller:用于标注控制层,控制层

@Service:用于标注服务层,service 层

@Repository:用于标注数据访问层,dao 层

@RestController = @Controller + @ResponseBody

作用:用于返回 json 数据。

使用示例(对比 IndexController1 和 IndexController2 完全理解)

IndexController1

IndexController2

访问路径为: >

在定义DAO和Service等其他bean的时候一般都会指定一个名称 如下:

@Repository("fnFunctionBasicDAO")

public class FnFunctionBasicDAOImpl {。。。。}

@Service("menuManager")

public class MenuManager{。。。。。}

使用resource注入就可以直接使用这个名字

我一般习惯于使用下面的方式注入

@Autowired

@Qualifier("menuManager")

private MenuManager menuManager;

jackson中,指定包含哪些属性、忽略哪些属性的注解:

用于标记忽略一个或多个属性。可以注解在类上、构造函数、方法、字段上。

@JsonIgnore注解用于在字段级别标记要忽略的属性。注意:系列化和反系列化时都会被忽略。

1、bean

2、测试

3、控制台输出

反系列化时,json数据中明明包含了category值,但是最后Article对象的category属性值依然为null。就是因为使用了JsonIgnore。

我们可以使用@JsonInclude排除某些empty、null、默认值的属性。

2、controller

没有在Result类上加 @JsonInclude(JsonIncludeIncludeNON_NULL) 注解时,返回的响应:

加了之后的返回的响应:

默认情况下,jackson获取public权限的字段进行系列化和反系列化。如果没有public权限的字段,就会去获取public修饰的getter/setter。使用 JsonAutoDetect注解,我们就可以修改默认的行为。比如,下面的案例,即使字段都是private的、也没有getter/setter,也照样获取字段。

1、bean

首先,我们定义一个属性id/name都私有的而且没有getter/setter的一个bean

2、反系列化测试:

报错:

3、系列化测试

报错:

4、bean上加上注解

5、再次分别测试反系列化、系列化

都运行正常,分别打印:

@ModelAttribute可以用于注解方法和参数。

@ModelAttribute可以用于注解方法和参数。

1、注解Controller中的方法时,返回的参数是一个属性值,@ModelAttribute注解的方法在Controller中每个URL处理方法调用之前,都会按照先后顺序执行。

2、注解Controller方法的参数,用于从model、Form表单或者URL请求参数中获取属性值。

例子如下,已在Spring30中验证通过。

@Controller

public class TestAction {

/---------------------@ModelAttribute注解一个方法---------------------/

/方法返回值为:void,没有什么意义/

@ModelAttribute

public void populateModel(ModelMap model) {

Systemoutprintln("---populateModel---");

modeladdAttribute("attributeName", "111");

}

/不指定指定属性名称,方法返回一个对象,相当于modeladdAttribute("user", user)/

@ModelAttribute

public User addUser() {

Systemoutprintln("---addUser---");

User user = new User();

usersetId(1);

usersetUsername("alan");

usersetPassword("1234");

return user;

}

/指定属性名称,方法返回一个字符串,相当于modeladdAttribute("string1-key", "string1-value")/

@ModelAttribute("string1-key")

public String addString() {

Systemoutprintln("---addString---");

return "string1-value";

}

/返回一个model属性,而不是视图名称/

@RequestMapping(value = "helloWorld1")

@ModelAttribute("attributeName")

public String helloWorld1() {

Systemoutprintln("---helloWorld1---");

return "hi";

}

/---------------------@ModelAttribute注解方法的参数---------------------/

/从模型中获取一个属性值,将其转换到对应类型的变量中/

@RequestMapping(value = "helloWorld")

public String helloWorld(@ModelAttribute("user") User user,

@ModelAttribute("attributeName") String aName,

@ModelAttribute("string1-value") String svalue) {

Systemoutprintln("---helloWorld---"+usergetUsername()+", "+usergetPassword());

Systemoutprintln("aName="+aName+", svalue="+svalue);

return "helloWorld";

}

/从Form表单或者URL参数中获取属性参数值,放到对应类型的参数中,注意:此时表单中的组件名和参数属性名称一致,如User对象有两个属性,分别为username,password,则表单中input的名称必须为username,password,才能实现属性值注入。

注意这个User类必须要有无参数的构造函数或者是setter方法

此时@ModelAttribute可以不用显式写/

@RequestMapping(value = "helloWorld2")

public String helloWorld2(@ModelAttribute("user") User user) {

Systemoutprintln("---helloWorld---"+usergetUsername()+", "+usergetPassword());

return "helloWorld";

}

}

为了使用C#提供的XML注释功能,注释应该使用特殊的注释语法(///)开头。在///之后,你可以使用预先定义的标签注释你的代码,也可以插入自己定义的标签。定制的标签将会在随后加入到生成的注释文档中。

<Summary> 对整体进行概要性描述

<summary>Description</summary>

类、属性(不推荐)、方法等

<para> 跟在Summary之后,对方法所涉及的入口参数进行有效的解释

<param name=username>本参数是用户的帐号</param>

方法的入口参数;

<returns> 对方法的返回值进行解释;

<returns>返回值零代表 *** 作成功,-1代表 *** 作不成功</returns>

方法的返回值;

<remarks> 对一些语句进行备注性描述

<remarks>本类需要调用另外一个User类相关方法</remarks>

类、方法、属性等;

<see> 在生成的文档中产生一个连接到其它描述的超链接;

<see cref=”[member]”/>

可以在其它注释标识符中加入

<seealso> 与上者的区别是本标识符显示超链接在一个文档的尾部的“See Also”区域,而前者在文档之中;

<seealso cref=”[member]”/>

不可以在其它注释标识符中加入

<value> 对一个属性进行概要性解释;

<value>这是一个public属性</value>

属性

<code> 如果需要置入一部分源代码段,可以使用本标识符将其标记出来

<code>

public int add(int a,b)

{return a+b;

}

</code>

可以在其它注释标识符中加入

<exception> 对程序中可能抛出的异常做解释;

<exception cref=”SystemException”>抛出的异常情况</exception>

在方法当中如果有抛出异常,如“try…catch结构”时可以使用本标识符做解释

<permission> 对方法的访问权限做一些解释:

<permission cref=”SystemSecurityPermissionSet”>这是公共方法</permission>

方法,属性

<c> 与<code>标识符基本相同,但本标识符仅用于单行代码;

<c>return a+b;</c>

可以在其它标识符中插入使用;

<example> 举例说明,通常与<code>配套使用;

<example> 以下示例说明如何调用Add方法:

<code>

class MyClass

{

  public static int Main()

{

return Add(1+2);

}

}

</code>

</example>

可以在其它标识符中插入;

<paramref> 在其它地方引用一个入口参数

<paramref cref=”a”>请注意,这是一个整型参数</paramref>

using System;

/// <summary>

/// ClassName:SomeClass

/// Version:10

/// Date:2001/6/21

/// Author:cniter

/// </summary>

/// <remarks>

/// 本类仅是一个示例教学类,不完成具体的工作

/// </remarks>

public class SomeClass

{

   /// <summary>

   /// 内部私有变量,存储名称</summary>

  private string myName = null;

   public SomeClass()

   {

       //

       // TODO: Add Constructor Logic here

       //

   }

  /// <summary>

  /// 名称属性 </summary>

  /// <value>

  ///本属性为只读属性,返回用户名</value>

  public string Name

  {

     get

     {

        if ( myName == null )

        {

           throw new Exception("Name is null");

        }

         

        return myName;

     }

  }

  /// <summary>

  /// 本方法是没有进行具体构建</summary>

  /// <param name="s"> 入口参数S是一个String类型</param>

  /// <seealso cref="String">

  ///String类型的信息</seealso>

  public void SomeMethod(string s)

  {

  }

  /// <summary>

  /// 本方法仍然没有进行具体构建</summary>

  /// <returns>

  /// 返回值始终为0</returns>

  /// <seealso cref="SomeMethod(string)">

  /// 参看SomeMethod(string)方法的说明 </seealso>

  public int SomeOtherMethod()

  {

     return 0;

  }

  /// <summary>

   /// 该应用程序的入口

  /// </summary>

  /// <param name="args"> 入口参数集合</param>

   public static int Main(String[] args)

   {

       //

       // TODO: Add code to start application here

       //

       return 0;

   }

}

以上就是关于通过注解和反射实现一个简单的@Value注解全部的内容,包括:通过注解和反射实现一个简单的@Value注解、@value注解获取属性文件的值怎么转换成int类型、六、Spring 中注解的使用及区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9701696.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存