Spring常⽤注解以及注解注⼊contextcomponent-scan详解1. ⾸先让我们来看分析下Spring注解@Component、@Repository、@Service、@Controller区别
spring 2.5 中除了提供 @Component 注释外,还定义了⼏个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。
在⽬前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。
虽然⽬前这3 个注释和 @Component 相⽐没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。
所以,如果 Web 应⽤程序采⽤了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采⽤上述注解对分层中的类进⾏注释。
@Controller⽤于标注控制层组件(如struts中的action,SpringMVC中的controller)
@Service⽤于标注业务或者对外提供Service服务API的组件
@Repository⽤于标注数据访问组件,即DAO组件
@Component泛指组件,当组件不好归类的时候,我们可以使⽤这个注解进⾏标注。
@Service
public class VentorServiceImpl implementsiVentorService {
}
@Repository
public class VentorDaoImpl implementsiVentorDao {
}
在⼀个稍⼤的项⽬中,如果组件采⽤xml的bean定义来配置,显然会增加配置⽂件的体积,查以及维护起来也不太⽅便。
Spring2.5为我们引⼊了组件⾃动扫描机制,他在类路径下寻标注了上述注解的类,并把这些类纳⼊进spring容器中管理。
它的作⽤和在xml⽂件中使⽤bean节点配置组件时⼀样的。要使⽤⾃动扫描机制,我们需要打开以下
配置信息:
代码
<?xml version="1.0"encoding="UTF-8" ?>
<beansxmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"
xsi:schemaLocation="/schema/beans
<context:component-scan base-package=”ic.spring”>
</beans>
1ponent-scan标签默认情况下⾃动扫描指定路径下的包(含所有⼦包),将带有@Component、@Repository、@Service、@Controller标签的类⾃动注册到spring容器。对标记了 Spring's @Required、@Autowired、JSR250's @PostConstruct、@PreDestroy、@Resource、JAX-
WS's@WebServiceRef、EJB3's @EJB、JPA's @PersistenceContext、@PersistenceUnit等注解的类进⾏对应的操作使注解⽣效(包含了annotation-config标签的作⽤)。
getBean的默认名称是类名(头字母⼩写),如果想⾃定义,可以@Service(“aaaaa”)这样来指定。
这种bean默认是“singleton”的,如果想改变,可以使⽤@Scope(“prototype”)来改变。
可以使⽤以下⽅式指定初始化⽅法和销毁⽅法:
@PostConstruct
public void init() {
}
@PreDestroy
public void destory() {
}
注⼊⽅式:
把DAO实现类注⼊到action的service接⼝(注意不要是service的实现类)中,注⼊时不要new 这个注⼊的类,因为spring会⾃动注⼊,如果⼿动再new的话会出现错误,
然后属性加上@Autowired后不需要getter()和setter()⽅法,Spring也会⾃动注⼊。
在接⼝前⾯标上@Autowired注释使得接⼝可以被容器注⼊,如:
@Autowired
@Qualifier("chinese")
private Man man;
当接⼝存在两个实现类的时候必须使⽤@Qualifier指定注⼊哪个实现类,否则可以省略,只写@Autowired。
2. Spring注解注⼊:<context:component-scan>详解
spring从2.5版本开始⽀持注解注⼊,注解注⼊可以省去很多的xml配置⼯作。由于注解是写⼊java代码中的,所以注解注⼊会失去⼀定的灵活性,我们要根据需要来选择是否启⽤注解注⼊。
我们⾸先看⼀个注解注⼊的实际例⼦,然后再详细介绍context:component-scan的使⽤。
如果你已经在⽤spring mvc的注解配置,那么你⼀定已经在使⽤注解注⼊了,本⽂不会涉及到spring mvc,我们⽤⼀个简单的例⼦来说明问题。
本例中我们会定义如下类:
1. PersonService类,给上层提供Person相关操作
2. PersonDao类,给PersonService类提供DAO⽅法
3. Person类,定义Person相关属性,是⼀个POJO
4. App类,⼊⼝类,调⽤注解注⼊的PersonService类
PersonService类实现如下:
package cn.outofmemory.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonService {
@Autowired
private PersonDao personDao;
public Person getPerson(int id) {
return personDao.selectPersonById(id);
}
}
在Service类上使⽤了@Service注解修饰,在它的私有字段PersonDao上⾯有@Autowired注解修饰。@Service告诉spring容器,这是⼀个Service类,默认情况会⾃动加载它到spring容器⾥。⽽@Autowired注解告诉spring,这个字段是需要⾃动注⼊的。
PersonDao类:
package cn.outofmemory.spring;
import t.annotation.Scope;
import org.springframework.stereotype.Repository;
@Scope("singleton")
@Repository
public class PersonDao {
public Person selectPersonById(int id) {
Person p = new Person();
p.setId(id);
p.setName("Person name");
return p;
}
}
在PersonDao类上⾯有两个注解,分别为@Scope和@Repository,前者指定此spring bean的scope是单例,你也可以根据需要将此bean指定为prototype,@Repository注解指定此类是⼀个容器类,是DA层类的实现。这个类我们只是简单的定义了⼀个selectPersonById⽅法,该⽅法的实现也是⼀个假的实现,只是声明了⼀个Person的新实例,然后设置了属性,返回他,在实际应⽤中DA层的类肯定是要从数据库或者其他存储中取数据的。
Person类:
package cn.outofmemory.spring;
public class Person {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person类是⼀个POJO。
App类:
package cn.outofmemory.spring;
import t.ApplicationContext;
import t.support.ClassPathXmlApplicationContext;
/**
* Hellospring! from outofmemory
*
*/
public class App
{
public static void main( String[] args )
{
ApplicationContext appContext = new ClassPathXmlApplicationContext("/l");
PersonService service = Bean(PersonService.class);
Person p = Person(1);
System.out.Name());
}
}
在App类的main⽅法中,我们初始化了ApplicationContext,然后从中得到我们注解注⼊的PersonService类,然后调⽤此对象的getPerson⽅法,并输出返回结果的name属性。
注解注⼊也必须在spring的配置⽂件中做配置,我们看下l⽂件的内容:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"springmvc的注解有哪些
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"
xsi:schemaLocation="/schema/beans
<context:component-scan base-package="cn.outofmemory.spring"use-default-filters="false">
<context:include-filter type="regex"expression="cn\.outofmemory\.spring\.[^.]+(Dao|Service)"/>
</context:component-scan>
</beans>
这个配置⽂件中必须声明xmlns:context 这个xml命名空间,在schemaLocation中需要指定schema:
/schema/context
/schema/context/spring-context-3.0.xsd
这个⽂件中beans根节点下只有⼀个context:component-scan节点,此节点有两个属性base-package属性告诉spring要扫描的包,use-default-
filters="false"表⽰不要使⽤默认的过滤器,此处的默认过滤器,会扫描包含Service,Component,Repository,Controller注解修饰的类,⽽此处我们处于⽰例的⽬的,故意将use-default-filters属性设置成了false。
context:component-scan节点允许有两个⼦节点<context:include-filter>和<context:exclude-filter>。filter标签的type和表达式说明如下:
Filter Type Examples Expression Description
ample.SomeAnnotation符合SomeAnnoation的target class
ample.SomeClass指定class或interface的全名
ample..*Service+AspectJ語法
regex org\.example\.Default.*Regelar Expression
ample.MyTypeFilter Spring3新增⾃訂Type,實作ype.TypeFilter
在我们的⽰例中,将filter的type设置成了正则表达式,regex,注意在正则⾥⾯.表⽰所有字符,⽽\.才表⽰真正的.字符。我们的正则表⽰以Dao或者Service结束的类。
我们也可以使⽤annotaion来限定,如下:
默认情况下,<context:component-scan>查使⽤构造型(stereotype)注解所标注的类,如@Component(组件),@Service(服
务),@Controller(控制器),@Repository(数据仓库)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论