java练习生 - 常用注解

 一、功能:依赖注入

Lombok注解:构造器注入:@RequiredArgsConstructor_ABin-阿斌的博客-CSDN博客_lombok 构造器注入

https://blog.csdn.net/isea533/article/details/78072133

https://blog.csdn.net/cw_szdx/article/details/106868298

1.1 创建实例并装配到Spring容器(IOC)中

@Bean 一般加在方法上,手动创建一个实例,并保留在IOC中。默认情况下bean的名称和方法名称相同,你也可以使用name属性来指定。当我们引用第三方库中的类需要装配到Spring容器时,则只能通过@Bean来实现,因为你并不能改他的源代码在他类上加个@Component )。

-- @Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为多例。

@Component 自动创建一个实例,并保留在IOC中。是通用注解,后面三个注解是这个注解的拓展,并且赋予了特定的功能

@Repository 注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。

@Controller 是spring-mvc的注解,具有将请求进行转发,重定向的功能。

@Service 是业务逻辑层注解,这个注解只是标注于该类处于业务逻辑层。

 

@Import(ServerA.class) 上面的Component相关注解是要加在需要创建bean的类上,也可以使用Import相关注解在要使用bean的类上直接将某个普通类或配置类加载到容器中,这样被使用的类就无效加Component注解了。

-- @EnableBinding、@EnableConfigurationProperties等都是使用的@Import

 

其他相关注解:

@Configuration 配置类注解,注解本质上还是 @Component,区别是@Configuration 中所有带 @Bean 注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。

-- 一般用来配合@Bean方法将第三方库中的类装配到容器;也可以配合@ConfigurationProperties注解来将配置文件的内容加载到自定义的配置类中。

@ConfigurationProperties 注解来将配置文件的内容加载到自定义的配置类中,还可以配合@Component相关注解,将配置类注册到ico中以便使用。

@Conditional 条件注入,用来控制什么时候应该注册bean对象,包括@ConditionalOnBean、@ConditionalOnClass、@ConditionalOnProperty、@ConditionalOnExpression等。

a. 可以作为类级别的注解直接或者间接的与@Component相关联,包括@Configuration类;
b. 作为方法级别的注解,作用在任何@Bean方法上。

c. 可以作为元注解,用于自动编写构造性注解;

 

-- 用这些注解对应用进行分层之后,就能将请求处理,义务逻辑处理,数据库操作处理等分离出来,为代码解耦,也方便了以后项目的维护和开发。

 

1.2 ICO中取出对应的实例,注入变量或方法参数

1.2.1 属性注入:

@Autowired和@Resource 一般用在变量上,spring容器会自动注入值。

@Autowired和@Resource 也可以用在方法上,spring容器会在类加载后自动注入这个方法的参数,并执行一遍方法

@Autowired 默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,例如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:

@Autowired() 
@Qualifier("baseDao")
private BaseDao baseDao;

@Resource 默认安装名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名查找实例,如果注解写在setter方法上则默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配,如下:

@Resource(name="baseDao")
private BaseDao baseDao;

-- @Autowired是基于类型匹配的,所以如果一个bean是collection或者map则不能用@Autowired而需要使用@Resource。

-- 相对来说推荐使用@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。

@Autowired 也支持这种基于接口实现的类直接注入到List和Map

@Service
public class OperationFactory {
    @Autowired
    private List<IOperation> operations = new ArrayList<>();
    // @Autowired
// private Map<String,IOperation> operationMap;  
    private Map<String , IOperation> operationMap = new HashMap<>();

    @PostConstruct
    private void init() {
        for (IOperation operation : operations) {
            operationMap.put(operation.getType(), operation);
        }
    }
    public IOperation getOperation(String type){
        return operationMap.get(type);
    }
}

 

1.2.2 构造器注入(官方推荐):

@RequiredArgsConstructor注解 会生成一个只包含【final】和【@NotNull注解】的变量的构造方法,并使用容器中的对象来初始化这些变量。

至于为什么不使用@AllArgsConstructor注解是因为这个注解是针对所有参数的,而在大多情境下,我们只需构造Bean所对应的属性而不是非Bean,所以我们只需在Bean对应的属性前加上final关键字进行修饰就可以只生成需要的有参构造函数。

@RequiredArgsConstructor
public class TestController {
    private final ServerA serverA;
    ...
}

 

1.2.3 Setter方法注入(官方推荐):

 

@Slf4j
@RestController
@RequestMapping("vpn")
public class VpnController {
        private final IkeInfo ike;
        private final IpSecInfo ipSec;

        @Autowired
        public void setIkeInfo (PointBiz1 ike) {
            this.ike= ike;
        }

        @Autowired
        public void setIpSecInfo (IpSecInfo ipSec) {
            this.ipSec= ipSec;
        }
...
}

 

-- 构造器对注入强制性的的依赖是好的。对象需要这些依赖才能正常运转,通过构造器提供这些依赖就能保证对象初始化后就能被使用。使用构造器注入的一个可能的影响就是循环依赖。
-- Setter 应该被用来注入可变的依赖。当没有提供依赖时,这个类也应该能够运转。当实例化对象后,这些依赖也能随时改变。其实也视情况而变,有时,一个不变的对象是理想状态。有时,最好是能在运行期间改变对象的属性。

 

1.3 按条件创建实例

@ConditionalOnExpression 根据是否满足某个条件来决定是否创建该类的实例到IOC。

支持语法如下:

@ConditionalOnExpression("${mq.server.enabled}==1&&${rabbitmq.server.enabled:true}")

@ConditionalOnExpression("'${mq.server}'.equals('test')")

 

二、功能:强化实体类

@Getter,@Setter 该注解用在类或属性上,可以为相应的属性自动生成Setter/Getter方法。

用法:

import lombok.Getter;
import lombok.Setter;
@Setter @Getter
public class User { private Integer id; private String name; private Integer age; private String sex; }


@ToString 该注解用在类上,可以生成toString()方法,默认情况下,会输出类名、所有属性(会按照属性定义顺序),用逗号来分割。如:【User(id=1, name=拉拉, age=20)】

用法:

import lombok.ToString;
@ToString
public class User { private Integer id; private String name; private Integer age; }

 

@EqualsAndHashCode 该注解用在类上,默认情况下,会使用所有非静态(non-static)和非瞬态(non-transient)属性来生成equals和hasCode,也能通过exclude注解来排除一些属性。

-- @EqualsAndHashCode(exclude={"id", "shape"}) :通过exclude参数来排除一些属性

-- @EqualsAndHashCode(of={"id", "shape"}):通过of参数来指定只使用一些属性

-- @EqualsAndHashCode(callSuper=true):默认仅使用该类中定义的属性且不使用父类的属性,可通过callSuper=true让其生成的方法中包含父类的属性。

 

 参考:lombok注解详解-@NoArgsConstructor、@RequiredArgsConstructor、@AllArgsConstructor的使用_小鸭子想去通天河煲汤的博客-CSDN博客_noargsconstructor注解

@NoArgsConstructor会生成一个无参数的构造方法。

 

@AllArgsContructor会生成一个包含所有变量的构造方法。

 

@RequiredArgsConstructor会生成一个只包含【final】和【标识了NotNull的变量】的构造方法。生成的构造方法是私有的private。

 

@Data该注解用在类上,相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集。该注解包含的@EqualsAndHashCode默认不包括父类的属性。如有必要,需同时加上@EqualsAndHashCode(callSuper=true)注解。

 

@Accessors(fluent = true) :fluent设置为true,则getter和setter方法的方法名都是基础属性名,且setter方法返回当前对象。

用法:

@Data
@Accessors(fluent = true)
public class User {
    private int id;
    private String name;
}

 

@Accessors(prefix = {"tb","tbn"}) :prefix设置为true,则用于生成getter和setter方法的字段名会忽视指定前缀(遵守驼峰命名)。

用法:

@Data
@Accessors(prefix = {"tb","tbn"})
public class User {
    private int tb_id;
    private String tbn_name;
}

 

@Accessors(chain = true) :chain设置为true,则setter方法返回当前对象。

用法:

@Data
@Accessors(chain = true)
public class User {
    private int id;
    private String name;
}

 

三、功能:参数检查

@Valid 该注解用在属性或方法入参上,表示当前的实体类接收的参数需要根据配置的校验注解进行判断。

 

-- 如果校验不通过,在全局异常中通过捕捉BindException来处理。

 

四、功能:协助业务

https://www.cnblogs.com/xiaomaomao/p/13934688.html

@Cleanup 该注解能帮助我们自动调用close()方法,很大的简化了代码。

用法:

import lombok.Cleanup;
public class CleanupExample {
  public static void main(String[] args) throws IOException {
    @Cleanup InputStream in = new FileInputStream(args[0]);
    @Cleanup OutputStream out = new FileOutputStream(args[1]);
    byte[] b = new byte[10000];
    while (true) {
      int r = in.read(b);
      if (r == -1) break;
      out.write(b, 0, r);
    }
  }
}

 

@ConfigurationProperties 让使用该标注类的属性绑定程序配置文件。

 

@EnableConfigurationProperties 让使用 @ConfigurationProperties 注解的类生效,并且将该类注入到Spring容器中,交由Spring容器进行管理。

 

 

@Slf4j 自动创建日志操作类的实例,相当于执行【private final Logger log = LoggerFactory.getLogger(当前类名.class);】语句,在标注的类中可以直接使用log.info(...)等打印日志。

 

@Value 自动获取程序配置并赋值,并可以通过冒号添加默认值,这样当配置不存在时会直接使用默认值,而避免抛异常。 

使用:

 

@Value("${server.port:8888}")
public String curAppPort;

 

 

五、功能:数据操作

https://blog.csdn.net/jiangyu1013/article/details/84397366

@Transactional事务支持。

1)接口实现类或接口实现方法上,而不是接口类中。
2)访问权限:public 的方法才起作用。@Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。
系统设计:将标签放置在需要进行事务管理的方法上,而不是放在所有接口实现类上:只读的接口就不需要事务管理,由于配置了@Transactional就需要AOP拦截及事务的处理,可能影响系统性能。

 

posted @ 2020-12-29 19:59  Ariter  阅读(186)  评论(0编辑  收藏  举报