這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)spring中注解處理框架解析以及源代碼實(shí)現(xiàn)是怎樣的,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
建網(wǎng)站原本是網(wǎng)站策劃師、網(wǎng)絡(luò)程序員、網(wǎng)頁設(shè)計(jì)師等,應(yīng)用各種網(wǎng)絡(luò)程序開發(fā)技術(shù)和網(wǎng)頁設(shè)計(jì)技術(shù)配合操作的協(xié)同工作。創(chuàng)新互聯(lián)專業(yè)提供網(wǎng)站制作、成都網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì),網(wǎng)站制作(企業(yè)站、響應(yīng)式網(wǎng)站、電商門戶網(wǎng)站)等服務(wù),從網(wǎng)站深度策劃、搜索引擎友好度優(yōu)化到用戶體驗(yàn)的提升,我們力求做到極致!
@Autowired和@Resource的區(qū)別:
在Java中使用@Autowired和@Resource注解進(jìn)行裝配,這兩個注解分別是:
1、@Autowired按照默認(rèn)類型(類名稱)裝配依賴對象,默認(rèn)情況下它要求依賴對象必須存在,如果允許為null,可以設(shè)置它的required屬性為false
如果我們按名稱裝配,可以結(jié)合@Qualifie注解一起使用。
如:
@Autowired @qualifie("personDaoBean")
private PersonDaoBean personDaoBean;
@Resource默認(rèn)按照名稱(name="test")進(jìn)行裝配,名稱可以通過@resource的name屬性設(shè)定,當(dāng)找不到與名稱匹配的bean才會按類型裝配
注意:如果沒有指定name屬性,并且安裝默認(rèn)的名稱依然找不到依賴對象時,@Resource會回退到按類型裝配。但一旦指定了name屬性,就只能按名稱裝配了。
下面的示例來簡單的講述spring注解原理:
實(shí)現(xiàn)了在set方法上和在字段屬性上注解的處理解析。
1、定義注解
Java代碼
package com.yt.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Description:定義注解
* @ClassName: ZxfResource
* @Project: spring-aop
* @Author: zxf
* @Date: 2011-6-7
*/
// 在運(yùn)行時執(zhí)行
@Retention(RetentionPolicy.RUNTIME)
// 注解適用地方(字段和方法)
@Target({ ElementType.FIELD, ElementType.METHOD })
public @interface ZxfResource {
//注解的name屬性
public String name() default "";
}
2、帶有注解的服務(wù)類
Java代碼
package com.yt.annotation;
/**
* @Description: 帶有注解的服務(wù)
* @ClassName: UserDaoImpl
* @Project: spring-aop
* @Author: zxf
* @Date: 2011-6-7
*/
public class UserServiceImpl {
public UserDaoImpl userDao;
public User1DaoImpl user1Dao;
// 字段上的注解,可以配置name屬性
@ZxfResource
public User2DaoImpl user2Dao;
// set方法上的注解,帶有name屬性
@ZxfResource(name = "userDao")
public void setUserDao(UserDaoImpl userDao) {
this.userDao = userDao;
}
// set方法上的注解,沒有配置name屬性
@ZxfResource
public void setUser1Dao(User1DaoImpl user1Dao) {
this.user1Dao = user1Dao;
}
public void show() {
userDao.show();
user1Dao.show1();
user2Dao.show2();
System.out.println("這里是Service方法........");
}
}
3、要注入的DAO
Java代碼
package com.yt.annotation;
/**
* @Description: 要注入的DAo類
* @ClassName: UserDaoImpl
* @Project: spring-aop
* @Author: zxf
* @Date: 2011-6-7
*/
public class UserDaoImpl {
String name ;
public void show(){
System.out.println("這里是dao方法........");
}
}
Xml代碼
4、注解處理器
Java代碼
package com.yt.annotation;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* @Description: spring中的注解原理
* @ClassName: ClassPathXMLApplicationContext
* @Project: spring-aop
* @Author: zxf
* @Date: 2011-6-3
*/
public class ClassPathXMLApplicationContext {
Logger log = Logger.getLogger(ClassPathXMLApplicationContext.class);
List
Map
public ClassPathXMLApplicationContext(String fileName) {
//讀取配置文件中管理的bean
this.readXML(fileName);
//實(shí)例化bean
this.instancesBean();
//注解處理器
this.annotationInject();
}
/**
* 讀取Bean配置文件
* @param fileName
* @return
*/
@SuppressWarnings("unchecked")
public void readXML(String fileName) {
Document document = null;
SAXReader saxReader = new SAXReader();
try {
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
document = saxReader.read(classLoader.getResourceAsStream(fileName));
Element beans = document.getRootElement();
for (Iterator
beansList.hasNext();) {
Element element = beansList.next();
BeanDefine bean = new BeanDefine(
element.attributeValue("id"),
element.attributeValue("class"));
beanList.add(bean);
}
} catch (DocumentException e) {
log.info("讀取配置文件出錯....");
}
}
/**
* 實(shí)例化Bean
*/
public void instancesBean() {
for (BeanDefine bean : beanList) {
try {
sigletions.put(bean.getId(),
Class.forName(bean.getClassName()).newInstance());
} catch (Exception e) {
log.info("實(shí)例化Bean出錯...");
}
}
}
/**
* 注解處理器
* 如果注解ZxfResource配置了name屬性,則根據(jù)name所指定的名稱獲取要注入的實(shí)例引用,
* 如果注解ZxfResource;沒有配置name屬性,則根據(jù)屬性所屬類型來掃描配置文件獲取要
* 注入的實(shí)例引用
*
*/
public void annotationInject(){
for(String beanName:sigletions.keySet()){
Object bean = sigletions.get(beanName);
if(bean!=null){
this.propertyAnnotation(bean);
this.fieldAnnotation(bean);
}
}
}
/**
* 處理在set方法加入的注解
* @param bean 處理的bean
*/
public void propertyAnnotation(Object bean){
try {
//獲取其屬性的描述
PropertyDescriptor[] ps =
Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDescriptor proderdesc : ps){
//獲取所有set方法
Method setter = proderdesc.getWriteMethod();
//判斷set方法是否定義了注解
if(setter!=null && setter.isAnnotationPresent(ZxfResource.class)){
//獲取當(dāng)前注解,并判斷name屬性是否為空
ZxfResource resource = setter.getAnnotation(ZxfResource.class);
String name ="";
Object value = null;
if(resource.name()!=null&&!"".equals(resource.name())){
//獲取注解的name屬性的內(nèi)容
name = resource.name();
value = sigletions.get(name);
}else{ //如果當(dāng)前注解沒有指定name屬性,則根據(jù)類型進(jìn)行匹配
for(String key : sigletions.keySet()){
//判斷當(dāng)前屬性所屬的類型是否在配置文件中存在
if(proderdesc.getPropertyType().isAssignableFrom(sigletions.get(key).getClass())){
//獲取類型匹配的實(shí)例對象
value = sigletions.get(key);
break;
}
}
}
//允許訪問private方法
setter.setAccessible(true);
//把引用對象注入屬性
setter.invoke(bean, value);
}
}
} catch (Exception e) {
log.info("set方法注解解析異常..........");
}
}
/**
* 處理在字段上的注解
* @param bean 處理的bean
*/
public void fieldAnnotation(Object bean){
try {
//獲取其全部的字段描述
Field[] fields = bean.getClass().getFields();
for(Field f : fields){
if(f!=null && f.isAnnotationPresent(ZxfResource.class)){
ZxfResource resource = f.getAnnotation(ZxfResource.class);
String name ="";
Object value = null;
if(resource.name()!=null&&!"".equals(resource.name())){
name = resource.name();
value = sigletions.get(name);
}else{
for(String key : sigletions.keySet()){
//判斷當(dāng)前屬性所屬的類型是否在配置文件中存在
if(f.getType().isAssignableFrom(sigletions.get(key).getClass())){
//獲取類型匹配的實(shí)例對象
value = sigletions.get(key);
break;
}
}
}
//允許訪問private字段
f.setAccessible(true);
//把引用對象注入屬性
f.set(bean, value);
}
}
} catch (Exception e) {
log.info("字段注解解析異常..........");
}
}
/**
* 獲取Map中的對應(yīng)的bean實(shí)例
* @param beanId
* @return
*/
public Object getBean(String beanId) {
return sigletions.get(beanId);
}
public static void main(String[] args) {
ClassPathXMLApplicationContext path = new ClassPathXMLApplicationContext(
"configAnnotation.xml");
UserServiceImpl userService =(UserServiceImpl)path.getBean("userService");
userService.show();
}
}
上述就是小編為大家分享的spring中注解處理框架解析以及源代碼實(shí)現(xiàn)是怎樣的了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。