欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

浅谈spring 常用注解

程序员文章站 2024-04-01 22:19:10
我们不妨先将spring常用的注解按照功能进行分类 1 、将普通类加入容器形成bean的注解 日常开发中主要使用到的定义bean的注解包括(xml方式配置bean暂...

我们不妨先将spring常用的注解按照功能进行分类

1 、将普通类加入容器形成bean的注解

日常开发中主要使用到的定义bean的注解包括(xml方式配置bean暂不讨论):

@component、@repository、@service、@controller、@bean

其中@component、@repository、@service、@controller实质上属于同一类注解,用法相同,功能相同,区别在于标识组件的类型。当一个组件代表数据访问层(dao)时,你可以给它加上@repository注解,如下例:

@repository
public class biliapidaoimpl implements biliapidao {
private final static logger logger = loggerfactory.getlogger(biliapidaoimpl.class);
 
private biliapihttpclient asoapihttpclient;
public void execute(){
  //some logic business
 }
}

当组件用于业务层时,使用@service注解,如下例:

@service(value="secuserservice")
public class secusersserviceimpl implements secusersservice {
 @autowired
 private secusersdao secusersdao;
 @autowired
 private secroleuserservice secroleuserservice;
 public void dobusiness(){
  //do some business
 }
 }

注意,在此处的@service注解中额外添加了value=”secuserservice”的属性,为何对此一举呢?value属性可以指定生成后bean的名称,这个名称便成为容器中bean 的唯一标识符。同样的,在@component、@repository、@controller也均可以指定其value值,当然,是如有必要时加

当组件属于控制层时,则使用@controller注解;当组件不能进行很好地归类时,那我们可以使用@component注解。因使用方式均相同,故此处不再继续贴代码

在这几个注解中,额外需要留意的是@bean注解。不妨看代码:

@component
public class factorymethodcomponent {
 
 private static int i;
 
 @bean @qualifier("public")
 public testbean publicinstance() {
  return new testbean("publicinstance");
 }
 
 // use of a custom qualifier and autowiring of method parameters
 
 @bean
 protected testbean protectedinstance(@qualifier("public") testbean spouse,
          @value("#{privateinstance.age}") string country) {
  testbean tb = new testbean("protectedinstance", 1);
  tb.setspouse(tb);
  tb.setcountry(country);
  return tb;
 }
 
 @bean @scope(beandefinition.scope_singleton)
 private testbean privateinstance() {
  return new testbean("privateinstance", i++);
 }
 
 @bean @scope(value = webapplicationcontext.scope_session,
    proxymode = scopedproxymode.target_class)
 public testbean requestscopedinstance() {
  return new testbean("requestscopedinstance", 3);
 }
}

bean注解主要用于方法上,有点类似于工厂方法,当使用了@bean注解,我们可以连续使用多种定义bean时用到的注解,譬如用@qualifier注解定义工厂方法的名称,用@scope注解定义该bean的作用域范围,譬如是singleton还是prototype等。

此处还得另外提一个注解: @configuration.实际上,上面谈到的@bean注解更多时候是与@configuration注解在一起使用的。如果将一个类标注为@configuration注解,那么也就意味着这个class将会作为创建各种bean的工厂(类似于一个新的容器)。最简单的配合使用示例如下:

@configuration
public class appconfig {
 @bean
 public myservice myservice() {
  return new myserviceimpl();
 }
}

以上的代码实际上等价于xml中的配置:

<beans>
 <bean class="com.acme.services.myserviceimpl" id="myservice">
</bean></beans>

我们还需要注意的一点,在spring的@component注解中使用@bean与在spring中的@configuration使用是一定的差别的。在使用@component的类中不会强制使用cglib代理拦截方法和属性。而在@configuration类中,则会使用cglib代理去调用@bean标注的方法并返回对象的引用。在@configuration注解中使用@bean也可以防止同一个@bean方法被意外调用多次时而产生细微的难以排查的错误

2、从容器中取bean(装配bean)时常用的注解

开发中最常用到的用于装配的注解是:@autowired和@resource

@autowired注解:

public class movierecommender {
 
 @autowired
 private moviecatalog moviecatalog;
 
 private customerpreferencedao customerpreferencedao;
 
 @autowired
 public movierecommender(customerpreferencedao customerpreferencedao) {
  this.customerpreferencedao = customerpreferencedao;
 }
 
 // ...
}

@autowired注解可用于为类的属性、构造器、方法进行注值。默认情况下,其依赖的对象必须存在(bean可用),如果需要改变这种默认方式,可以设置其required属性为false。另外一个比较重要的点就是,@autowired注解默认按照类型装配,如果容器中包含多个同一类型的bean,那么启动容器时会报找不到指定类型bean的异常,解决办法是结合@qualified注解进行限定,指定注入的bean名称

@resource注解
对于@resource注解,它并不属于spring的注解,而是来自于jsr-250。其默认情况下按照bean的名称进行注入,当找不到匹配项时会按照类型装配。当按照名称进行装配时,可以指定其name属性,倘若没有指定,注解标注在哪个字段上,其默认名称就是那个字段的名称。当然,@resource注解也支持按指定类型进行装配,给它的type属性赋特定类型的值即可(注意,当指定了name属性后,只能按照名称装配)

public class springanotationdemo {
 
 @bean
 @qualifier("httpapiclient")
 public httpapiclient createhttpclient() {
  return new httpapiclient();
 }
 
 @resource(name = "httpapiclient")
 private httpapiclient httpapiclient;
 @resource(type = xqsmshttpclient.class)
 private smshttpclient smshttpclient;
}

依我个人理解,其实@resource要比@autowired好用得多,@resource注解的使用性更为灵活,可指定名称,也可以指定类型 ,而用@autowired注解进行装配容易抛出异常,特别是装配的bean类型有多个的时候,而解决的办法是需要在增加@qualitied进行限定

vc模块注解">3、spring mvc模块注解
web模块常用到的注解包括:

@controller、@requestmapping、@requestparam、@pathvariable

@controller
将一个类加上@controller注解后,表明该类会作为与前端作交互的控制层组件

@controller
public class companycontroller {
/**this class will be the controller component of container**/
...
}

@requestmapping
这个注解用于将url映射到整个处理类或者特定的处理请求的方法

@controller
@requestmapping("/company")
public class companycontroller {
 
 @autowired
 private companyservice companyservice;
...
}

如上例,当标注在class上时,表明此类会接收url为”/company”请求

@requestparam
用于绑定request请求参数到指定的方法

@controller
@requestmapping("/company")
public class companycontroller {
 
 @autowired
 private companyservice companyservice;
 
 @requestmapping("/companylist")
 public string listcompanies(map<string, object=""> map, 
    @requestparam(value = "data", required = false) string data,
    @requestparam(value = "phone_num", required = true) string phonenum) {
 map.put("data", data);
 map.put("phonenum", phonenum);
 return "companylist";
 }
...
}

譬如上例中,@requestparam请求参数指定了传入参数的具体字段名(value指定的),以及是否必须传的字段(默认情况下,required=true)。data,phonenum为形参,即请求参数的使用名,可以更改

@pathvariable
该注解用于方法修饰方法参数,会将修饰的方法参数变为可供使用的uri变量(可用于动态绑定),请看如下栗子:

@controller
@requestmapping("/company")
public class companycontroller {
 
 @autowired
 private companyservice companyservice;
 
 @requestmapping("{companyname}")
 public string getcompany(map<string, object=""> map, 
   @pathvariable string companyname) {
 company company = companyservice.findbyname(companyname);
 map.put("company", company);
 return "company";
 }
...
}

当我们请求 “/compony/account”时,componyname会动态地绑定为”account”

4、事务模块注解@transactional

在处理dao层或service层的事务操作时,譬如删除失败时的回滚操作,可用到@transactional注解,如下例:

@service
public class companyserviceimpl implements companyservice {
 @autowired
 private companydao companydao;
 
 @transactional(propagation = propagation.required, readonly = false, rollbackfor = exception.class)
 public int deletebyname(string name) {
 
 int result = companydao.deletebyname(name);
 return company;
 }
 ...
}

上例表明,执行deletebyname方法时,启用了事务处理,事务的各属性含义如下:

propagation
事务的传播行为,spring在transactiondefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时如何进行传播:

事务传播行为类型 描述
propagation_required 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
propagation_supports 支持当前事务,如果当前没有事务,就以非事务方式执行。
propagation_mandatory 使用当前的事务,如果当前没有事务,就抛出异常。
propagation_requires_new 新建事务,如果当前存在事务,把当前事务挂起。
propagation_not_supported 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
propagation_never 以非事务方式执行,如果当前存在事务,则抛出异常
propagation_nested 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类 似的操作

注:第一种是最常用的,默认的

readonly
事务的读写属性,取true或者false,true为只读、默认为false rollbackfor
回滚策略,当遇到指定异常时回滚。譬如上例遇到异常就回滚 timeout (补充的)
设置超时时间,单位为秒 isolation
设置事务隔离级别,枚举类型,一共五种

类型 描述
default 采用默认隔离级别
read_uncommitted 读未提交的数据(会出现脏读取)
read_committed 读已提交的数据(会出现幻读,即前后两次读的不一样)
repeatable_read 可重复读,会出现幻读
serializable 串行化(对资源消耗较大,一般不使用)

5、 spring aop模块注解
spring aop模块的注解主要有@aspect、@pointcut、@before、@around、@after、
@afterreturning、@afterthrowing

@aspect
标明该类为切面类,并启用aspectj注解,注:在使用时要同@component一起使用,否则不会被扫描到加入容器

@pointcut
定义切入点,关于切入点表达式书写方式,请移步官方文档:spring aop文档

@around
定义环绕通知,在目标方法执行前后嵌入相关业务逻辑

@before
定义前置通知,在目标方法执行前执行

@after
定义后置通知,在目标方法执行后执行,不论是目标方法执行正常后退出,还是抛出异常后退出,均会被执行

@afterreturning
目标方法执行正常退出后执行 @afterthrowing
目标方法执行抛出异常后执行

总结

以上就是本文关于浅谈spring 常用注解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅:

java之spring注解配置bean实例代码解析

浅谈java注解和动态代理

有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!