Spring常用注解

Spring中常用注解

组件注解

@Component("xxx")

指定某个类是容器的bean,@Component(value="xx")相当于,其中value可以不写。用于标注类为容器bean的注解有四个,主要用于区别不同的组件类,提高代码的可读性

@Component

用于标注一个普通的类

@Controller

用于标注一个控制器类

@Service

用于标注业务逻辑类

@Repository

用于标注DAO数据访问类

现在这几个注解没有什么区别,尽量根据类的不同功能选择合适的注解。注解用于修饰类,当不写value属性值时,默认值为类名首字母小写。

组件扫描注解

@ComponentScan

bean相关注解

@Bean

@Scope("prototype")

该注解和@Component这一类注解联合使用,用于标记该类的作用域,默认为singleton,也可以和bean一起使用,此时@scope修饰一个方法

@DependsOn({"aa","bb"})

该注解也是配合@Component这类注解使用,用于强制初始化其他bean

@Lazy(true)

指定bean是否延时初始化,相当于<bean id="xx" lazy-init=""> ,默认false。@Lazy可以和@Component这一类注解联合使用修饰类,也可以和@Bean一起使用修饰方法

@DepondsOn("other")
@Lazy(true)
@Controller
@Scope("prototype")
public class UserAction{
	...............
}

上面的代码指定,初始化bean “userAction"之前需要先初始化“aa”和“bb”两个bean,但是使用了@Lazy(true)所以spring容器初始化时不会初始化"userAction” bean。

bean(singlton作用域)的生命周期的行为注解

@PostConstruct

构造器之后调用相当于 就是在依赖注入之后执行

@PreDestroy

容器销毁之前bean调用的方法,相当于

两者修饰方法来管理容器中spring生命周期行为.

自动装配

@Resource(name="xxx")

可以修饰变量成员也可以修饰成员方法,当修饰成员变量时可以不写set方法,此时spring会直接使用jee规范的Field注入

两个比较重要的属性,name和type

  • 如果指定了name和type,则从Spring容器中找到唯一匹配的bean进行装配,找不到则抛出异常;
  • 如果指定了name,则从spring容器查找名称(id)匹配的bean进行装配,找不到则抛出异常;
  • 如果指定了type,则从spring容器中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常;
  • 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配

如果没有写name属性值时

  • 修饰成员变量,此时name为成员变量名称
  • 修饰set方法,此时name 为set方法的去掉set后首字母小写得到的字符串

@Autowired(requird=false)

可以修饰构造器,成员变量,set方法,普通方法,默认使用byType方式自动装配,required标记该类型的bean是否是必须的,默认为必须存在(true)

  • required=true(默认),为true时,从spring容器查找和指定类型匹配的bean,匹配不到或匹配多个则抛出异常
  • 使用@Qualifier("xx"),则会从spring容器中匹配类型和id一直的bean,匹配不到抛出异常

@Autowired会根据修饰的成员选取不同的类型

  • 修饰成员变量。该类型为成员变量类型
  • 修饰方法,构造器。注入类型为参数的数据类型,当然可以有多个参数

@Qualifier

//service层,业务逻辑
@Service
public class UserService{
	
	@Resource(name="userDao")
	private UserDao userDao;
	//@Autowired
	//@Qualifier("userDao")
	//private IUserDao userDao;
	//相对来说使用`@Resource`更简单一些
	.......实际业务.............
}

//dao层,持久化
@Repository
@Lazy(true)
@Scope("singleton")
public class UserDao implements InitializingBean,DisposableBean{
	public UserDao() {
		System.out.println("constructor...................");
	}
	
	public List<User> listUsers(){
		System.out.println("查询所有用户");
	}
	@PostConstruct
	public void postConstructor() {
		System.out.println("post_constructor.................");
	}
	
	//覆盖InitializingBean接口方法
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("after_properties_set..............");
		
	}
	
	@PreDestroy
	public void after() {
		System.out.println("pre_destroty.................");
	}
	//重写DisposableBean方法
	@Override
	public void destroy() throws Exception {
		System.out.println("destry_method.............");
	}
}

//测试类
public class TestAnnotation{
	@Test 
	public void test1(){
		ClassPathXmlApplicationContext application=new ClassPathXmlApplicationContext("applicationContext.xml");
		//配置文件里只有一行就是开启自动扫描” <context:component-scan base-package="com" /> “
		System.out.println("-------------------");
		System.out.println(application.getBean("userDao"));
	}
}

AOP相关注解

该注解是AspectJ中的注解,并不是spring提供的,所以还需要导入aspectjweaver.jar,aspectjrt.jar,除此之外还需要依赖aopalliance.jar

@Aspect

修饰java类,指定该类为切面类,spring不会对该bean做增强处理

@Before("pointcut_expresisson")

修饰方法,before增强处理

@AfterReturning

修饰方法,afterreturning增强处理,目标方法正常结束后做增强处理

常用属性

  • pointcut/value:定义切入点
  • returning:指定一个参数名,用于接受目标方法正常结束时返回的值。在增强方法中定义同名的参数

@AfterThrowing

修饰方法,afterthrowing增强处理。当目标程序方法抛出 异常或者异常无法捕获时,做增强处理。
常用属性

  • pointcut/value :指定切入点表达式
  • throwing:指定一个形参,在增强方法中定义同名形参,用于访问目标方法抛出的异常

@After

修饰方法 ,after增强处理。无论方法是否正常结束,都会调用该增强处理(@After= @AfterReturning+@AfterThrowing)。一般用于释放资源。
有一个value属性,用于指定切入点表达式。

@Arround

修饰方法, around增强处理。该处理可以目标方法执行之前和执行之后织入增强处理,可以看作时@Before和@AfterReturning的总和。
有一个value属性,指定切入点表达式。

Around增强处理通常需要在线程安全的环境下使用,如果@Before和@AfterReturning可以处理就没必要使用@After Returning

当定义一个Around增前处理时,增强方法第一形参需要时ProceedingJoinPoint类型。ProceedingJoin Point有一个Object proceed()方法,用于执行目标方法,返回对象当然也可以为目标方法传递数组参数。

//切面类
@Aspect
public class UserAdvice{
	
	@Pointcut("execution(* com.User*.*(..))")
	public void userAdvice(){}
	
	@Before(value="userAdvice()")
	public void authority(){
		System.out.println("权限检查。。。");
	}
	
	@AfterReturning(pointcut="userAdvice")
	public void log(){
		System.out.println("写入日志。。。");
	}
	
	@After("userAdvice()")
	public void release(){
		System.out.println("资源释放。。。");
	}
	
	@Around("userAdvice()")
	public void arround(ProceedingJoinPoint joinPoint){
		System.out.println("开启事务。。。");
		joinPoint.proceed(jointPoint.getArgs());
		System.out.println("关闭事务。。。");
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xsi:schemaLocation="  
        http://www.springframework.org/schema/beans       
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-3.0.xsd  
        http://www.springframework.org/schema/aop  
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">  
  
    <context:component-scan base-package="com" />  <!--自动扫描-->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy><!--开启@AspectJ支持-->
</beans> 
//测试类
public class TestAnnotation{
    @Test 
    public void test1(){
        ClassPathXmlApplicationContext application=new ClassPathXmlApplicationContext("applicationContext.xml");
        //配置文件里只有一行就是开启自动扫描” <context:component-scan base-package="com" /> “
       IUserDao userDao = application.getBean("userDao",UserDao.class);
       userDao.listUsers();
    }
} 

输出结果

constructor...................
post_constructor.................
after_properties_set..............
开启事务。。。
权限检查。。。
System.out.println("查询所有用户");
关闭事务。。。
资源释放。。。
写入日志。。。
pre_destroty.................
destry.............
pre_destroty.................
destry.............

spring aop采用和AspectJ相同的优先顺序织入,进入连接连接点时,具有最高优先级的增强处理先被织入,在退出优先级时最高优先级的增强处理先被执行。

@Pointcut

修饰方法,定义一个切入点,用于被其他增强调用。

切入点的定义和普通定义类似

@Pointcut("execution(* user*(..))")
//使用一个返回值为void,空方法体的方法命名切入点。
//public 为修饰符,跟方法的修饰符一致,public 可以在其他切面类中使用该切点,default在同一个包下的切面类中使用该切点
//返回值必须为void , 方法名就是定义的切点名称
public  void userAdvice(){}

@Order

当不同的切面中的两个增强处理需要在同一个连接点被织入时,spring aop可以指定不同切面类的增强处理优先级。
有一个value属性,指定一个int值,属性值越小优先级越高。

切入点表达式

execution表达式格式

execution(modifiers-pattern? return-type-pattern declaring-type-pattern? method-name(param-pattern) throws-pattern?)
注:?表示出现一次或零次
  • modifers-pattern:指定方法的修饰符,支持通配符,可以省略
  • return-type-pattern ;方法返回值类型,必写可以使用通配符,表示所有返回值类型
  • declaring-type-pattern:全限定类名。可以省略,表示所有类。可以使用通配符com.example.dao.User,表示 匹配com.example.dao包下,所有以User开头的类
  • method-name:指定方法名,必写。可以使用通配符*,表示所有方法。
  • param-pattern:方法参数,必写。可以使用通配符* ,表示任意一个参数类型。也可以使用通配符…,表示零个或多个任意类型的参数。(*,String),表示第一个参数类型任意,第二个必须为String类型。
  • throws-pattern:方法抛出异常,可以省略

within1. 匹配指定类下的所有方法。 2. 匹配执行包下所有类下的所有方法

@annotation

用于匹配当前执行方法持有指定注解的方法;

@within

用于匹配指定注解修饰类下的所有方法

AOP配置

@Component
@EnableAspectJAutoProxy
@Aspect
public class ControllerLog {

    @Pointcut(value="execution(* com.example.controller.*.*(..))")
    public void addLog(){}
    //任意类
    @Pointcut(value="within(com.example.controller.*)")
    public void withinMethod(){}

    @Pointcut(value="@within(com.example.annotation.ParamAnnotation)")
    public void withinAnnotation(){}

    @Pointcut(value="@annotation(com.example.annotation.ParamAnnotation)")
    public void annotationAnnotation(){}


    @Before(value = "addLog()")
    public void execute(JoinPoint joinPoint){
        System.out.println("增强处理。。。。。。。。。。。。");
        Signature signature = joinPoint.getSignature();
        System.out.println(signature.getName());
        System.out.println(signature.getDeclaringTypeName());
        System.out.println("增强处理结束!!");
    }

    @Before(value = "withinMethod()")
    public void within(JoinPoint joinPoint){
        System.out.println("       withinMethod  增强处理。。。。。。。。。。。。");
        System.out.println("       withinMethod 增强处理结束!!");

    }


    @Before(value = "withinAnnotation()")
    public void executeWithAnnotation(JoinPoint joinPoint){
        System.out.println("withinAnnotation  增强处理。。。。。。。。。。。。");
        System.out.println("withinAnnotation  增强处理结束!!");
    }

    @Before(value = "annotationAnnotation()")
    public void annotationAnnotation(JoinPoint joinPoint){
        System.out.println("annotationAnnotation  增强处理。。。。。。。。。。。。");
        System.out.println("annotationAnnotation  增强处理结束!!");
    }

}

接口

@Controller
@ParamAnnotation
public class UserController {
    @Autowired
    private IUserDao userDao;

    @ParamAnnotation
    @RequestMapping("/users")
    @ResponseBody
    public Object searchUsers(Model model){
        System.out.println("---------------");
        List<User> users=userDao.searchUsers();
        return users;
    }


     @RequestMapping("/hello")
    @ResponseBody
    public String hello(){
        return "hello world";
    }
}

测试结果

1.调用/users

	annotationAnnotation  增强处理。。。。。。。。。。。。
annotationAnnotation  增强处理结束!!
增强处理。。。。。。。。。。。。
searchUsers
com.example.controller.UserController
增强处理结束!!
withinAnnotation  增强处理。。。。。。。。。。。。
withinAnnotation  增强处理结束!!
       withinMethod  增强处理。。。。。。。。。。。。
       withinMethod 增强处理结束!!
-----searchUses----------

2.调用/hello

增强处理。。。。。。。。。。。。
hello
com.example.controller.UserController
增强处理结束!!
withinAnnotation  增强处理。。。。。。。。。。。。
withinAnnotation  增强处理结束!!
       withinMethod  增强处理。。。。。。。。。。。。
       withinMethod 增强处理结束!!

Java配置类相关注解

@Configuration

作用于类上,相当于一个xml配置文件;

@Import({xxxx.class})

修饰java类,用于向当前配置类导入其他java配置类

@ImportResource("classpath:aaa.xml")

修饰Java类,用于向当前注解类导入xml配置文件

上面两个都是用于配置的导入相当于<import resource="">元素

@Value("${expression}")

修饰成员变量,或者方法构造器的参数,常用于注入文件中的值,不能对static属性注入

@ConfigurationProperties

用于从主属性文件中获取值 application.properties 或者 application.yml。当然了 如果在属性文件中引入其他配置文件,也可以获取到属性值。

  • value | prefix 两者互为别名。指定前缀,默认为""
  • ignoreUnknownFields:默认为true。是否忽略未知字段,当实体中的字段在配置文件中不存在时,是忽略还是抛出异常
  • ignoreInvalidFields: 默认false。 是否忽略不合法的字段,此处的不合法是指类型不合适,配置文件中存在改配置但是无法转化为指定的字段类型。

ConfigurationProperties 可以配置前缀,然后会根据实体的变量名拼接前缀,去配置文件中查询配置

# 开发环境的配置文件 application-dev.properties
# 通常会配置三套, 生产,测试,本地
# 将通用部分配置存放在 application.yml,譬如 数据库连接等信息存放在application-xxx.yml中。这样不用每次都要繁琐的修改。
spring.profiles.active=dev
#  配置mybatis 
mybatis.configuration.mapperLocations=classpath:mybatis/mapper/*.xml
mybatis.configuration.typeAliasPackage=com.example.domain
mybatis.configuration.configLocation=classpath:mybatis/mybatis-config.xml
@Component
@ConfigurationProperties(prefix="mybatis.configuration")
public class MybatisProperties {

    private String configLocation ; //配置文件的路径等价于  @Value("mybatis.configuration.configLocation")
    private String mapperLocations; //配置Mapper映射文件的路径
    private String typeAliasPackage; //别名的实体路径
    public String getConfigLocation() {
        return configLocation;
    }

    public void setConfigLocation(String configLocation) {
        this.configLocation = configLocation;
    }

    public String getMapperLocations() {
        return mapperLocations;
    }

    public void setMapperLocations(String mapperLocations) {
        this.mapperLocations = mapperLocations;
    }

    public String getTypeAliasPackage() {
        return typeAliasPackage;
    }

    public void setTypeAliasPackage(String typeAliasPackage) {
        this.typeAliasPackage = typeAliasPackage;
    }
}

@Bean (name="xxx")

作用于方法上,相当于xml配置中的

常用的属性

name:bean id 。name可以省略,省略时name值为方法名。
autowire: 是否自动注入,默认Autowire.NO
initMethod:bean的初始化方法。在依赖注入之后执行
destroyMethod: spring容器关闭时bean调用的方法

当然@Bean还可以配合@Scope指定bean的作用域

@Configuration //通过该注解来表明该类是一个Spring的配置,相当于一个xml文件
@ComponentScan(basePackages = "cn.springboot.javaconfig") //配置扫描包
public class SpringConfig {//SpringConfig 用于实例化Spring容器
    @Bean // 通过该注解来表明是一个Bean对象,相当于xml中的<bean>
    public UserDAO getUserDAO(){
        return new UserDAO(); // 直接new对象做演示
    }
}

@Configuration
public class UserConfiguration{
	
	@Bean(name="userDao")
	public UserDao userDao(){
		return new UserDao();
	}
	
	@Bean
	public UserService userService(){
		UserService service=new UserService();
		service.setUserDao(userDAo());
		return service;
	}
}

@PropertySoure(value="classpath:jdbc.properties")

用于加载配置文件,但和Configurationproperties有些不同

使用该注解加载的配置文件就是相对独立文件。例如 :数据源的配置信息我们可以配置在application.yml 中,也可以将该部分内容单独放在一个文件里(jdbc.properties)。

存在的属性:

  • ignoreResourceNotFound: 当资源文件找不到的时候是否会忽略该配置,而不是抛出错误。一般用于可选项
  • encoding : 资源文件使用什么编码方式
#数据源配置
spring.datasource.url=xxxxxxxx
spring.datasource.username=xxxx
..............................
@Configuration
@PropertySource(value="classpath:jdbc.properties")
public class DatasourceConfig {
	private Logger logger = LoggerFactory.getLogger(DatasourceConfig.class);

    @Value("${spring.datasource.url}")
    private String dbUrl;
    
    @Value("${spring.datasource.type}")
    private String dbType;
    
    @Value("${spring.datasource.username}")
    private String username;
    
    @Value("${spring.datasource.password}")
    private String password;
    
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    
    @Value("${spring.datasource.initialSize}")
    private int initialSize;
    
    @Value("${spring.datasource.maxActive}")
    private int maxActive;
    
    @Value("${spring.datasource.maxWait}")
    private int maxWait;
    
    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;
    
    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;
    
    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;
    
    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;
    
    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;
    
    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;
    
    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;
    
    @Value("${spring.datasource.filters}")
    private String filters;
    
    @Value("${spring.datasource.druidLoginName}")  
    private String druidLoginName;  
      
    @Value("${spring.datasource.druidPassword}")  
    private String druidPassword; 
    
	@Bean(name="dataSource",destroyMethod = "close", initMethod="init")
    @Primary 
    public DataSource dataSource(){  
        DruidDataSource datasource = new DruidDataSource();  
        try {  
	        datasource.setUrl(this.dbUrl);  
	        datasource.setDbType(dbType);
	        datasource.setUsername(username);  
	        datasource.setPassword(password);  
	        datasource.setDriverClassName(driverClassName);  
	        datasource.setInitialSize(initialSize);  
	        datasource.setMinIdle(minIdle);  
	        datasource.setMaxActive(maxActive);  
	        datasource.setMaxWait(maxWait);  
	        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  
	        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  
	        datasource.setValidationQuery(validationQuery);  
	        datasource.setTestWhileIdle(testWhileIdle);  
	        datasource.setTestOnBorrow(testOnBorrow);  
	        datasource.setTestOnReturn(testOnReturn);  
	        datasource.setPoolPreparedStatements(poolPreparedStatements);  
            datasource.setFilters(filters);  
        } catch (SQLException e) {  
            logger.error("druid configuration initialization filter", e);  
        }  
        return datasource;  
    } 
}

SpringMVC相关注解

@Controller

标记一个类为SpringMVC Controller 对象

@RequestMapping

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

@Resource和@Autowired

@PathVariable

@CookieValue

@RequestParam

@SessionAttributes

@ModelAttribute

@RequestBody

从Reuqest请求体中获取内容,绑定到方法的指定参数上。 请求体内容使用HttpMessageConverter 转化方法参数类型。

SpringMVC 给用户对参数的处理提供了很大支配权。 我们可以使用 RequestBodyAdvice 来实现对参数进行拦截处理。

注意

RequestBodyAdvice : 针对所有以@RequestBody的参数做处理
自定义的处理对象类上必须得加上@ControllerAdvice注解!
利用此功能我们就可以对参数做加密处理。定义一个注解。用来控制参数是否加密

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SecurityParameter {
    /**
     * 入参是否解密,默认解密
     */
    boolean inDecode() default true;

    /**
     * 出参是否加密,默认加密
     */
    boolean outEncode() default true;
}

@ResponseBody

将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;

SpringBoot中常用注解

SpringCloud中常用注解

原文地址:https://www.cnblogs.com/lishisan/p/11235362.html