@Component 元注解
@Component 元注解
這是一個元注解,意思是它可以用于標(biāo)注其他注解,被它標(biāo)注的注解和它起到相同或者類似的作用。Spring用它定義了其他具有特定意義的注解如@Controller @Service @Repository。如下是Spring中 @Service的定義:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // Spring will see this and treat @Service in the same way as @Component
public @interface Service {
}
另外@Controller 和 @Repository與之類似。Spring在web項目賦予這些注解特殊的含義。分別表示控制器和 數(shù)據(jù)訪問層。
自定義
我們可以自定義注解,如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface MyComponent {
String value();
}
使用
我們現(xiàn)在可以使用(自定義)注解直接標(biāo)注在某個類上,此類就會自動的被Spring容器注冊為BeanDefinition,我們可以對上篇文章中在xml中定義的bean改也注解的方式進(jìn)行聲明:
//使用元注解
@Component("user1")
public class UserServiceIml1 implements UserService{
private UserDao userDao;
@Override
public List<User> getUser() {
return userDao.getUser();
}
//標(biāo)注在set方法上。
@Autowired
public void setUserDao(@Qualifier("userDao") UserDao userDao) {
this.userDao = userDao;
}
}
//使用自定義注解
@MyComponent("user2")
public class UserServiceIml2 implements UserService{
//標(biāo)注在字段上。
@Autowired
@Qualifier("userDao")
private UserDao userDao;
@Override
public List<User> getUser() {
return userDao.getUser();
}
}
以上使用注解后,我們需要做一些配置是Spring啟用類路徑掃描(classpath-scan),在XML配置中加入以下配置,這個配置就自動啟用了注解的相關(guān)功能:
<context:component-scan base-package="com.test"/>
以上注解表示自動掃描com.test包及其子包下被@component(或者其擴(kuò)展)表中的類,并把他們注冊為bean。以上配置還有其他屬性,可以定義專門的過濾器做自定義的配置。
以下為一個示例:
<context:component-scan base-package="org.example">
<context:include-filter type="regex"
expression=".*Stub.*Repository"/>
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
@Bean
在采用XML配置bean的時候,我們可以使用實(shí)例工廠來定義一個Bean,采用@Bean注解我們也可以做到類似的形式。在一個Bean中定義另外一個Bean。這通過在@Component的標(biāo)注類中對某個方法使用@Bean進(jìn)行注解。
如下所示:
@Bean(name="getService")
@Qualifier("getService")
public UserService getService(@Qualifier("userDao") UserDao user){
UserService ser = new UserServiceIml1();
return ser;
}
上述定義一個Bean,并定義了Name和Qualifier屬性。還可以定義Scope,Lazy等屬性。見下個小節(jié)。
其實(shí)@Bean更多的是與@Confuguration一起使用,來構(gòu)建另外一種不同于基于XML的ApplicationContext,即基于注解的,AnnotationConfigApplicationContext。這個以后討論。
命名和其他屬性
命名
基于@Componet及其擴(kuò)展(如@Servic和自定義等)標(biāo)注和classpath-scan定義的Bean,注解有一個value屬性,如果提供了,那么就此Bean的名字。如果不提供。就會使用Spring默認(rèn)的命名機(jī)制,即簡單類名且第一個字母小寫,見如下示例:
@Component("user5")
//Bean的名稱是user5
public class UserServiceIml5 implements UserService{
}
@Component()
//Bean的名稱是userServiceIml3
public class UserServiceIml3 implements UserService{
}
我們可以更新Spring默認(rèn)的命名機(jī)制,只要我們實(shí)現(xiàn)了相關(guān)接口BeanNameGenerator,并進(jìn)行配置,如下:
<context:component-scan base-package="org.example"
name-generator="org.example.MyNameGenerator" />
其他
在基于XML的配置中bean標(biāo)簽還有很多屬性,如scope、Lazy、init-method、depends-on、Qualifier等。下面通過一個簡單的配置例子說明:
package com.test.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
import com.test.bo.User;
import com.test.dao.UserDao;
import com.test.dao.UserDaoImp;
import com.test.service.UserService;
//使用元注解
@Component("user1")
@Qualifier("user1")
@Lazy(true)
@DependsOn("userDao")
public class UserServiceIml1 implements UserService{
private UserDao userDao;
@Override
public List<User> getUser() {
return userDao.getUser();
}
//標(biāo)注在set方法上。
@Autowired
public void setUserDao(@Qualifier("userDao") UserDao userDao) {
this.userDao = userDao;
}
@Bean(name="getService",initMethod="init1",destroyMethod="close1")
@Qualifier("getService")
@Scope(value="singleton")
@Lazy(true)
@DependsOn("getDao")
public UserService getService(@Qualifier("getDao") UserDao user){
System.out.println("------------getService is creted when used--------------");
System.out.println(user.getClass().toString());
UserService ser = new UserServiceIml1();
return ser;
}
@Bean(name = "getDao")
@Qualifier("getDao")
@Scope(value="prototype",proxyMode=ScopedProxyMode.TARGET_CLASS)
@Lazy(true)
public UserDao getDao(){
System.out.println("------------getDao is creted when used--------------");
return new UserDaoImp();
}
private void init1(){
System.out.println("---------getService init1----------------");
}
private void close1(){
System.out.println("---------getService close----------------");
}
public UserDao getUserDao() {
return userDao;
}
}
上述分別在類上和某個方法上,加入了很多的屬性配置,可以和傳統(tǒng)的XMl的配置比較。主要singleton引用其他類型時,需要生成代理。
@Configuration
Spring提供一種基于注解的applicationContext,實(shí)際應(yīng)用中,它可以和XML的配置聯(lián)合使用或者各自單獨(dú)使用。當(dāng)使用時,需要很大的利用的@Bean注解。
下面給一個簡單的例子,其他的詳細(xì)例子見Spring官方文檔。
首先是一個@Configuration 的配置類,定義了兩個Bean。
@Configuration
public class MyAnnoConfig {
@Bean(name="cDao1")
public UserDao getConfigDao(){
return new UserDaoImp();
}
@Bean(name="cs1")
public UserService getConfigS(@Qualifier("cDao1") UserDao dao){
UserServiceIml us =new UserServiceIml();
us.setUserDao(dao);
return us;
}
}
下面是測試函數(shù)。
public class TestAnnoContextMain {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyAnnoConfig.class);
UserService us = ctx.getBean("cs1",UserService.class);
System.out.println(us.getUser());
}
}
總結(jié)
本篇較詳細(xì)的說明了Spring支持的Bean級別的注解的使用方法,主要介紹了@Component和@Bean(在@component中使用),并穿插介紹了一些Bean屬性的注解。最后注意舉例說明Spring的基于注解的applicationContext和@configuration。
注意,本篇沒有介紹JSR-330的注解@Named,其和@Component基本一致,但不如前者強(qiáng)大。并且我認(rèn)為只要比較清楚的一種方式的原理和使用方法,其他的都是舉一反三的例子=,這也是不詳細(xì)寫@configuration的原因(其實(shí)它和@Bean配合,和基于XML的配置的功能幾乎一樣)。本完整測試代碼0分
總結(jié)
以上是生活随笔為你收集整理的@Component 元注解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字体大宝库:16款漂亮的免费英文手写字体
- 下一篇: 消息称索尼 5 月 29 日开启 Pla