您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關spring中注解處理框架解析以及源代碼實現是怎樣的,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
@Autowired和@Resource的區別:
在Java中使用@Autowired和@Resource注解進行裝配,這兩個注解分別是:
1、@Autowired按照默認類型(類名稱)裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許為null,可以設置它的required屬性為false
如果我們按名稱裝配,可以結合@Qualifie注解一起使用。
如:
@Autowired @qualifie("personDaoBean")
private PersonDaoBean personDaoBean;
@Resource默認按照名稱(name="test")進行裝配,名稱可以通過@resource的name屬性設定,當找不到與名稱匹配的bean才會按類型裝配
注意:如果沒有指定name屬性,并且安裝默認的名稱依然找不到依賴對象時,@Resource會回退到按類型裝配。但一旦指定了name屬性,就只能按名稱裝配了。
下面的示例來簡單的講述spring注解原理:
實現了在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
*/
// 在運行時執行
@Retention(RetentionPolicy.RUNTIME)
// 注解適用地方(字段和方法)
@Target({ ElementType.FIELD, ElementType.METHOD })
public @interface ZxfResource {
//注解的name屬性
public String name() default "";
}
2、帶有注解的服務類
Java代碼
package com.yt.annotation;
/**
* @Description: 帶有注解的服務
* @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代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id = "userDao" class="com.yt.annotation.UserDaoImpl" />
<bean id = "user1Dao" class="com.yt.annotation.User1DaoImpl" />
<bean id = "user2Dao" class="com.yt.annotation.User2DaoImpl" />
<bean id = "userService" class = "com.yt.annotation.UserServiceImpl" />
</beans>
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<BeanDefine> beanList = new ArrayList<BeanDefine>();
Map<String, Object> sigletions = new HashMap<String, Object>();
public ClassPathXMLApplicationContext(String fileName) {
//讀取配置文件中管理的bean
this.readXML(fileName);
//實例化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<Element> beansList = beans.elementIterator();
beansList.hasNext();) {
Element element = beansList.next();
BeanDefine bean = new BeanDefine(
element.attributeValue("id"),
element.attributeValue("class"));
beanList.add(bean);
}
} catch (DocumentException e) {
log.info("讀取配置文件出錯....");
}
}
/**
* 實例化Bean
*/
public void instancesBean() {
for (BeanDefine bean : beanList) {
try {
sigletions.put(bean.getId(),
Class.forName(bean.getClassName()).newInstance());
} catch (Exception e) {
log.info("實例化Bean出錯...");
}
}
}
/**
* 注解處理器
* 如果注解ZxfResource配置了name屬性,則根據name所指定的名稱獲取要注入的實例引用,
* 如果注解ZxfResource;沒有配置name屬性,則根據屬性所屬類型來掃描配置文件獲取要
* 注入的實例引用
*
*/
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)){
//獲取當前注解,并判斷name屬性是否為空
ZxfResource resource = setter.getAnnotation(ZxfResource.class);
String name ="";
Object value = null;
if(resource.name()!=null&&!"".equals(resource.name())){
//獲取注解的name屬性的內容
name = resource.name();
value = sigletions.get(name);
}else{ //如果當前注解沒有指定name屬性,則根據類型進行匹配
for(String key : sigletions.keySet()){
//判斷當前屬性所屬的類型是否在配置文件中存在
if(proderdesc.getPropertyType().isAssignableFrom(sigletions.get(key).getClass())){
//獲取類型匹配的實例對象
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()){
//判斷當前屬性所屬的類型是否在配置文件中存在
if(f.getType().isAssignableFrom(sigletions.get(key).getClass())){
//獲取類型匹配的實例對象
value = sigletions.get(key);
break;
}
}
}
//允許訪問private字段
f.setAccessible(true);
//把引用對象注入屬性
f.set(bean, value);
}
}
} catch (Exception e) {
log.info("字段注解解析異常..........");
}
}
/**
* 獲取Map中的對應的bean實例
* @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中注解處理框架解析以及源代碼實現是怎樣的了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。