zoukankan      html  css  js  c++  java
  • 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中常用注解

  • 相关阅读:
    批处理操作
    注册表操作
    js 表格操作(兼容模式
    asp解码.net传参
    windows+nginx 查看并发链接数
    windows+nginx负载测试
    开发cocos2dx真机插件遇到问题,以及心得
    react路由
    Redux实现原理解析及应用
    test
  • 原文地址:https://www.cnblogs.com/lishisan/p/11235362.html
Copyright © 2011-2022 走看看