Java注解

java基本注解

注解

注解与注释的区别
  • 注释 :增强代码的可阅读性,并不会对程序的执行产生任何影响。
  • 注解 :给编译器或运行时环境提供额外的信息,能够影响程序的编译或运行行为。
常见注解
@Override  

明确标记一个方法是覆盖(重写)了父类中的方法

class Animal {
    void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Dog barks");
    }
}
@Deprecated

标记一个类、方法或字段已过时,不推荐使用

@Deprecated
public void oldMethod() {
    // 过时的方法
}
@SuppressWarnings

作用:抑制编译器警告。

  1. @SuppressWarnings(“unchecked”) [^ 抑制单类型的警告]
  2. @SuppressWarnings(“unchecked”,“rawtypes”) [^ 抑制多类型的警告]
  3. @SuppressWarnings(“all”) [^ 抑制所有类型的警告]
@Retention

RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;也就是编译时有效。
RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;加载时被抛弃。
RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;一直有效!

@Target

@Target:@Target只能用在注解上,指定修饰的注解的使用范围

@Inherited

如果一个类用上了@Inherited修饰的注解,那么其子类也会继承这个注解。

 @Repeatable

需要以下两个步骤:

  1. 定义一个可重复的注解,并使用 @Repeatable 指定其容器注解。

  2. 定义一个容器注解,用于存储多个可重复的注解。

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

// 定义可重复的注解
@Repeatable(MyAnnotations.class) // 指定容器注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}

// 定义容器注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
    MyAnnotation[] value(); // 存储多个 MyAnnotation 注解
}

// 使用可重复的注解
@MyAnnotation("First")
@MyAnnotation("Second")
public class MyClass {
    // 类逻辑
}

注意事项:

@Repeatable 所声明的注解,其元注解@Target的使用范围要比@Repeatable的值声明的注解中的@Target的范围要大或相同,否则编译器错误,显示@Repeatable值所声明的注解的元注解@Target不是@Repeatable声明的注解的@Target的子集
@Repeatable注解声明的注解的元注解@Retention的周期要比@Repeatable的值指向的注解的@Retention得周期要小或相同。

 

自定义注解
  1. 修饰符: 访问修饰符必须为public,不写默认为pubic;
  2. 关键字: 关键字为@interface;
  3. 注解名称: 注解名称为自定义注解的名称,使用时还会用到;
  4. 注解内容: 注解中内容,对注解的描述。
public @interface MyAnnotation {
    String value(); // 注解属性
    int priority() default 0; // 带默认值的注解属性
}

反射

概念

在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;

常用API

1.只能拿到public方法(包括继承的类或接口的方法)

public Method[] getMethods()

2.getDeclaredMethods返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

public Method[] getDeclaredMethods()

3.在Class对象和Method对象是都存在isAnnotationPresent这个方法的,作用是判断它是否应用了某个注解

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}

4.通过 getAnnotation() 方法来获取 Annotation 对象。

 public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}

5.或者是 getAnnotations() 方法,获取所有的注解

如果获取到的 Annotation 如果不为 null,则就可以调用它们的属性方法了。

public Annotation[] getAnnotations() {}

6.获取到Annotation之后,就可以通过annotationType获取注解的class结构信息,有了class信息就可以获取注解的变量名,等等

Class<? extends Annotation> annotationType();

7.getParameterAnnotations :返回表示按照声明顺序对此 Method 对象所表示方法的形参进行注释的那个数组的数组

public Annotation[][] getParameterAnnotations();

反射与注解

读取类上的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    public int id() default -1;

    public String msg() default "Hi";
}
import java.lang.reflect.Method;

@TestAnnotation(id = 222,msg = "awdawd")
public class Test {
    public static void main(String[] args) {
        Method[] declaredMethods1 = TestAnnotation.class.getDeclaredMethods();
        for (Method meth : declaredMethods1) {
            System.out.println("注解的变量名为:" + meth.getName());
        }

        // 首先判断Test类上是否使用了TestAnnotation注解
        boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);
        if (hasAnnotation) {
            // 获取注解,这个相当于是真正的拿到注解了,只有获取到这个才能获取到注解当中设置的值
            TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class);
            System.out.println("id:" + testAnnotation.id());
            System.out.println("msg:" + testAnnotation.msg());
        }
    }
}

读取方法上的注解
public class User {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    @Init("louis")
    public User setName(String name) {
        this.name = name;
        return this;
    }

    public String getAge() {
        return age;
    }

    @Init("22")
    public User setAge(String age) {
        this.age = age;
        return this;
    }
}
//读取注解信息
public class ReadAnnotationInfoTest {
    public static void main(String[] args) throws Exception {
        // 测试AnnotationTest类,得到此类的类对象
        Class c = Class.forName("com.gzl.cn.springbootnacos.my.User");
        // 获取该类所有声明的方法
        Method[] methods = c.getDeclaredMethods();
        // 声明注解集合
        Annotation[] annotations;
        // 遍历所有的方法得到各方法上面的注解信息
        for (Method method : methods) {
            // 获取每个方法上面所声明的所有注解信息
            annotations = method.getDeclaredAnnotations();
            System.out.println("方法名为:" + method.getName());

            if (method.isAnnotationPresent(Init.class)){
                Init annotation = method.getAnnotation(Init.class);
                System.out.println("注解设置的value值为:" + annotation.value());
            }

            for (Annotation an : annotations) {
                System.out.println("其上面的注解为:" + an.annotationType().getSimpleName());
                // 获取注解class对象
                Class<? extends Annotation> aClass = an.annotationType();
                // 通过class对象获取他的所有属性方法
                Method[] meths = aClass.getDeclaredMethods();
                // 遍历每个注解的所有变量
                for (Method meth : meths) {
                    System.out.println("注解的变量名为:" + meth.getName());
                }
            }
        }
    }
}

读取字段上的注解
读取方法参数注解
注解配合枚举使用

Spring基本注解

1.@Controller、@Service、 @Repository、 @Configuration
用于标注各个层级的注解,注入到spring容器管理:

@Controller 标注于控制层
@Service 标注于业务层
@Repository 标注于dao持久层
@Configuration 标注于配置层
 

@Controller
@RequestMapping(value = "/api/user")
public class UserController {
}
2. @Bean

@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。

示例:
在src根目录下创建一个AppConfig的配置类,这个配置类也就是管理一个或多个bean 的配置类,并在其内部声明一个userService的bean

@Configuration
public class AppConfig {
    @Bean
    public UserService userService(AccountRepository accountRepository) {
        return new UserServiceImpl(accountRepository);
    }
}

这个配置就等同于之前在xml里的配置:
@Configuration可理解为用spring的时候xml里面的< beans >标签
@Bean可理解为用spring的时候xml里面的< bean >标签

<beans>
    <bean id="userService" class="com.test.UserServiceImpl"  depends-on="accountRepository"/>
</beans>
3. @ResponseBody、@RequestMapping、@RequestBody

@ResponseBody:
该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中。

@RequestMapping:
该方法用来处理请求地址映射的注解。

@RequestBody:
用于接收前端请求的Json参数,并且封装到对应的JavaBean。

示例:

@Controller
public class UserContorller{
	@Autowired
	private UserService userService;
	
	@ResponseBody
	@RequestMapping(value = "userLogin", method = RequestMethod.POST)
	// 将前端ajax发出的请求写入User对象中
	public String login(@RequestBody User user) {   
	    return userService.getLogin(user);    
	}
}

SpringBoot基本注解

 @Component、@ConfigurationProperties、@Value

@Component:
实现bean的注入,当类不属于各种归类的时候(不属于@Controller、@Services等的时候),就可以使用@Component来标注这个类。

@ConfigurationProperties:
批量注入.properties配置文件中的属性,prefix的值是properties文件中属性的前缀。

@Value:
单个注入.properties配置文件中的属性。
 

配置文件内容:

spring.datasource.url=jdbc:mysql://127.0.0.1:8888/test?useUnicode=false&autoReconnect=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

Java类-@ConfigurationProperties写法:

@Component
@Data
@ConfigurationProperties(prefix = "spring.datasource")
public class DataBaseConfig {

    public String url;
    public String username;
    public String password;
    // 配置文件中是driver-class-name, 转驼峰命名便可以绑定成
    public String driverClassName;
    public String type;
}

Java类-@Value写法:

@Component
@Data
public class DataBaseConfig {
	
	@Value("${spring.datasource.url}")
    public String url;
    @Value("${spring.datasource.username}")
    public String username;
    @Value("${spring.datasource.password}")
    public String password;
    // 配置文件中是driver-class-name, 转驼峰命名便可以绑定成
    @Value("${spring.datasource.driver-class-name}")
    public String driverClassName;
    @Value("${spring.datasource.type}")
    public String type;
}

用法:

@Controller
@RequestMapping(value = "/config")
public class ConfigurationPropertiesController {

    @Autowired
    private DataBaseConfig dataBaseConfig ;

    @RequestMapping("/test")
    @ResponseBody
    public Map<String, Object> test(){

        Map<String, Object> map = new HashMap<>();
        map.put("url", dataBaseConfig.url);
        map.put("userName", dataBaseConfig.username);
        map.put("password", dataBaseConfig.password);
        map.put("className", dataBaseConfig.driverClassName);
        map.put("type", dataBaseConfig.type);

        return map;
    }
}
@Mapper和@MapperScan(Mybatis注解)

在使用Mybatis持久层框架来操作数据库时,使用@Mapper注解和@MapperScan注解来将Mapper接口类交给Sprinig进行管理,能够让其他类进行引用。

@Mapper:
在dao接口类中,添加此注解。麻烦点在于每个dao接口类都必须添加此注解;

示例:

@Repository
@Mapper
public interface UserDao {
}

@MapperScan:
可以指定要扫描的dao接口类的包路径,可以在启动类中添加此注解,可替代@Mapper注解(此包下的dao接口类不用再添加@Mapper注解)

示例:

@SpringBootApplication 
@MapperScan("com.test.dao")  
public class TestDemoApplication{  
    public static void main(String[] args) {  
       SpringApplication.run(TestDemoApplication.class, args);  
    }  
}
@SpringBootApplication

@SpringBootApplication的作用等价于同时组合使用@EnableAutoConfiguration,@ComponentScan,@SpringBootConfiguration,是这三个注解的复合注解。每次写三个会显得极其麻烦,将其整合。

Springboot是通过注解@EnableAutoConfiguration的方式,去查找、过滤、加载所需的配置文件,@ComponentScan扫描我们自定义的bean,@SpringBootConfiguration使得被@SpringBootApplication注解的类声明为注解类。

@SpringBootApplication默认扫描主程序所在的包以及所有子包内的组件。如果需要改变扫描路径,带上参数scanBasePackages则会扫描指定路径。

@SpringBootApplication(scanBasePackages={"com.test"})
public class TestDemoApplication{  
    public static void main(String[] args) {  
       SpringApplication.run(TestDemoApplication.class, args);  
    }  
}
@Autowired、@Resource

注入bean的两个注解,其中:

@Autowired是Spring自带的
@Resource是JSR250规范的实现,需要导入javax.annotation实现注入
在Spring框架中,如果在Service层中需要注入其他依赖的对象,通常我们都会使用@Autowired或者@Resource注解,两者使用上没有太大区别。

只是@Autowired跟Spring框架强耦合了, 如果换成其他框架,@Autowired就没作用了。而@Resource是JSR-250提供的,它是Java标准,绝大部分框架都支持。

    @Autowired
    private UserDao userDao;
	//默认需要配置与变量名一致,一般会指定一个name属性
    @Resource(name = "userDao")
    private UserDao userDao;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值