java注解、spring bean

自学了好一阵子,发现java注解这块实在是太重要了,故拿出来作为一篇笔记。

一、定义

1、注解与类、接口、枚举是在同一个层次,可以成为java 的一个类型。
2、注解是一种元数据,它是一种描述数据的数据,其作用在于提供程序本身以外的一些数据信息,
也就是说他不会属于程序代码本身,不参与逻辑运算,故而不会对原程序代码的操作产生直接的影响。

@Override
public String toString() {
    return"This is String Representation of current object.";
}

注解有什么好处?
1、@Override告诉编译器这是一个重写方法(描述方法的元数据),
2、父类中不存在该方法,编译器便会报错。
3、如果拼写错误,例如将toString()写成了toStrring(),也不用@Override注解,程序依然能编译运行,但这不是我的期望结果。

参考来源:https://blog.csdn.net/fei20121106/article/details/73733207

大致分为三类:自定义注解、JDK内置注解、还有第三方框架提供的注解。

1、自定义注解

public class test {
//    自定义注解:
//    返回值类型只能是(基本类型、Class、String、enum)
//    如果只有1个参数且名为value,使用时可以不用name=value的格式
//    有设置默认值可以不写,比如Annotation2的age
    @Annotation1("")
    @Annotation2(value = "",employees = {"张三"})
    @Annotation3()
    public void testAnnotation(){};
}

// 四个元注解:
// 元注解是注解的注解
// Target表示注解使用范围,Retention表示在什么地方还有效
// Documented表示生成javadoc文档,Inherited表示子类可以继承父类的注解
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface Annotation1{
    String value();
}

@Target(ElementType.METHOD)
@interface Annotation2{
    String value();
    String[] employees();
    int age() default 12;
}

@interface Annotation3{
}

2、 内置注解
  @Overide 重写
  @Deprecated 不推荐使用,但是可以使用
  @SuppressWarnings 抑制编译时的警告信息
    抑制单类型的警告   @SuppressWarnings("unchecked")
    抑制多类型的警告   @SuppressWarnings(value={"unchecked", "rawtypes"})
    抑制所有类型的警告  @SuppressWarnings("all")

3、第三方注解

  比如 lombok、spring框架的注解

二、 spring bean

这里涉及到ioc概念,之前的文章有写:https://www.cnblogs.com/yinwenbin/p/15170294.html

Bean是Spring框架中最核心的两个概念之一,另一个是面向切面编程AOP;
在 Spring 中,构成应用程序主干并由Spring IoC容器管理的对象称为bean
类的实例化、依赖的实例化、依赖的传入  都交由 Spring  IoC容器控制, 而不是用new方式实例化对象、通过非构造函数方法传入依赖等常规方式。

bean规范如下:
1、所有属性为private
2、提供默认构造方法
3、提供getter和setter
4、实现serializable接口

注册和使用,参考来源:https://zhuanlan.zhihu.com/p/99870991
使用Bean:即是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装;比如@Autowired , @Resource(@Autowired注解由Spring提供,只按照byType注 入;@resource注解由J2EE提供,默认按照byName自动注入
注册Bean:这些注解都是把你要实例化的对象转化成一个Bean,放在Spring IoC容器中
  @Component , 组件
  @Repository ,数据库层组件
  @Controller , 控制器组件
  @Service ,业务逻辑组件
  @Configuration , 配置组件
  @Bean
    1、用于显式声明单个bean,而不是让Spring像上面那样自动执行它。它将bean的声明与类定义分离,并允许您精确地创建和配置bean。
    2、如果想将第三方的类变成组件,你又没有没有源代码,也就没办法使用@Component进行自动配置,这种时候使用@Bean就比较合适了。
    3、@Bean则常和@Configuration注解搭配使用。

有些项目不想一个一个从xml迁移,只需要随便在某一个配置类上添加注解@ImportResource,示例:@ImportResource("classpath:beans.xml")

下面示例是在springboot运行的,先创建2个pojo类

package com.example.demo.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private Integer age;

    private Pet pet;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}
View Code
package com.example.demo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Pet {
    private String name;
}
View Code

再创建config类

package com.example.demo.config;

import ch.qos.logback.core.db.DBHelper;
import com.example.demo.pojo.Pet;
import com.example.demo.pojo.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/*
1、配置类里面用 @Bean 标注在方法上给容器注册组件,默认也是单实例
2、配置类本身也是组件
3、proxyBeanMethods :代理bean的方法,默认为true
 */
@Import({User.class, DBHelper.class}) //给容器中自动创建出这2个组件
@Configuration(proxyBeanMethods = false) //告诉spring boot这是一个配置类==配置文件
public class Myconfig {

    /*
    proxyBeanMethods
    如果为True, 获取到的类组件就是代理对象。代理对象多次调用组件方法,每次都会检查容器是否有实例对象,
    保持组件单实例。配置类组件间有依赖时使用
    如果为false,获取到的类组件就是普通对象。普通对象多次调用组件方法,不会检查容器是否有实例对象(导致springboot启动会比较快),
    会产生多个实例。配置类组件间无依赖时使用
     */
    @ConditionalOnBean(name = "ziDingYi") //如果容器中有该组件才注册bean,放在类上则下面的函数都会生效。加载顺序问题,用@ConditionalOnClass靠谱一点
    @Bean //给容器中添加组件,以方法名作为组件的id,第一个字母小写。返回类型就是组件类型。方法返回的值就是组件在容器中的实例
    public User user02(){
        User zhangsan=new User("张三",18);
        // User 组件依赖了 Pet组件。如果proxyBeanMethods为false,那么下一行的tomcatPet()会创建新的实例
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }


    @Bean("ziDingYi") // 这里的 ziDingYi 是我们自定义的组件id
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

最后在主程序验证

package com.example.demo;

import com.example.demo.config.Myconfig;
import com.example.demo.pojo.Pet;
import com.example.demo.pojo.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);

        //查看容器的组件
        String[] names=run.getBeanDefinitionNames();
        for (String name:names){
            System.out.println(name);
        }

        // 从容器中获取组件3种方法
        // 根据id、类型查找bean(getBean的返回类型是T,传入Pet.class则意味着返回Pet类型)
        Pet pet=run.getBean("ziDingYi", Pet.class);
        System.out.println("Pet实例:"+pet);

        // 按照id查找bean(返回的类型是object,所以要强转)
        User user =(User)run.getBean("user02");
        System.out.println("User实例:"+user);

        // 按照类型查找bean(要求该类型只有唯一的对象,否则不能找到)
        Myconfig bean = run.getBean(Myconfig.class);
        System.out.println("Myconfig 实例:"+bean);

        // 如果proxyBeanMethods为true,则打印结果为true,否则反之。
        System.out.println("测试proxyBeanMethods为true、false的情况:"+(user.getPet()==pet));
    }
}

 从properties文件装配2种方法 

mycar.name=BYD
mycar.price=100000

方法1、在pojo类上添加注解 @Component、@ConfigurationProperties

@Component
@ConfigurationProperties(prefix = "mycar")
@Data
public class Car {
    private String name;
    private Integer price;
}
View Code

方法2、在配置类添加注解 @EnableConfigurationProperties、在pojo类添加@ConfigurationProperties,适用于第三方的类注册进来

//@Component
@ConfigurationProperties(prefix = "mycar")
@Data
public class Car {
    private String name;
    private Integer price;
}
View Code
@Configuration(proxyBeanMethods = false) //告诉spring boot这是一个配置类==配置文件
@EnableConfigurationProperties(Car.class)
public class Myconfig {
View Code
一个只会点点点的测试,有疑问可以在测试群(群号:330405140)问我
原文地址:https://www.cnblogs.com/yinwenbin/p/15322009.html