Spring回顾一
<br />Spring回顾一<br />Spring是一个开源的控制反转(Inversion of Control, IoC)和面向切面的(AOP, Aspect-Oriented Programming)的容器框架,它的主要目的是简化企业的开发。<br />所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的,这样控制权就由应用转移到了外部容器,控制权的转
Spring回顾一
Spring是一个开源的控制反转(Inversion of Control, IoC)和面向切面的(AOP, Aspect-Oriented Programming)的容器框架,它的主要目的是简化企业的开发。
所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的,这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。
所谓依赖注入(Dependency Injection)就是指:在运行时,由外部容器动态地将依赖对象注入到组件中。
Spring的好处:
减低组件之间的耦合度,实现软件各层之间的解耦
可以使用Spring提供的众多服务,如:事务管理器,消息服务等等。
容器提供单例模式的支持
容器提供了AOP技术
容器提供了众多的辅助类,使用这些类能够加快应用的开发
Spring对于主流的应用框架提供了集成的支持
对于spring容器,提供了很多的服务,但这些服务不是默认为应用打开的。如果提高服务较少则认为是轻量级的,否则则认为是重量级的。
spring用到的核心jar文件有两个:
dist/spring.jar
lib/jakarta-commons/commons-logging.jar
如果使用了切面编程(AOP),还需要下列的jar文件
lib/aspectj/aspectjweaver.jar和aspectjrt.jar
lib/cglig/cglib-nodep-2.1-3.jar
如果使用了JSP-250中的注解,
如@Resource/@PostConstruct/@PreDestory,还需要下列jar文件
lib/j2ee/common-annotations.jar.
实例化Spring容器常用的两种方式:
方法一:
在类路径下寻找配置文件来实例化容器
ApplicationContext ctx =
new ClassPathXmlApplicationContext(new String[]{“bean.xml”});
方法二:
在文件系统路径下寻找配置文件实例化容器
ApplicationContext ctx =
new FileSystemXmlApplicationContext(new String[]{“d:/beans.xml”});
编写spring配置文件时不出现帮助信息
由于spring的schema文件位于网络上,如果机器不能连接到网络上,那么在编写配置信息时候无法出现提示信息,解决办法有两种:
1. 让机器上网,eclipse会自动从网络上下载schema文件并缓存到本地硬盘上。
2. 手动添加schema文件,方法如下:
windows->preferences->myeclipse->files and editors ->xml->xmllocation 点”add”,在出现的窗口中的Key Type中选择URL,在location中选择”File System”,然后在spring解压目录的dist/resources目录中选择spring-beans-2.5.xsd,回到设置窗口的时候不要急着关闭窗口,应把窗口中的Key Type改为Schema location,Key
改为http://www.springframework.org/schema/beans/srping-beans
-2.5.xsd.
<bean有id属性和name属性,name属性可以包含特殊字符例如:”/sd/
三种实例化bean的方式:
1. 使用类构造器实例化:
<bean id=”orderService” class=”cn.itcast.OrderServiceBean”>
2. 使用静态工厂的方法实例化:
<bean id=”personService” class=”cn.itcast.service.OrderFactory” factory-method=”createOrder” />
3. 使用实例化工厂的方法实例化:
<bean id=”personServiceFactory” class=”cn.itcast.service.OrderFactory” />
<bean id=”personSercie” factory-bean=”personServiceFactory” factory-method=”createOrder”>
Bean的作用域:
.singleton在每个Spring IoC容器中一个bean定义只有一个对象实例,默认情况下会在容器启动时初始化bean.但我们可以指定Bean节点的lazy-init=”true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:
<bean id=”xxx” class=”cn.itcast.OrderServiceBean” lazy-init=”true” />
如果想对所有的bean都应用延迟初始化,可以在跟节点beans设置default-laza-init=”true”,如下: <beans default-lazy-init=”true”>
.prototype 每次从从其获取bean都是新的对象。
以下仅用于Web Bean
.request
.session.
.global session
Spring管理Bean的声明周期:
init-method: bean初始化实例时,调用初始化方法。
destroy-method: bean被销毁时执行的方法。
AbstractApplicationContext.close()方法用于关闭Spring容器
Spring的依赖注入:
使用内部bean,但该bean不能被其他bean使用:
<bean id=”orderService” class=”cn.itcast.service.OrderServiceBean”>
<property name=”orderDao”>
<bean class=”cn.itcast.service.OrderDaoBean” />
</property>
</bean>
JavaBean是一种特殊的Java类,主要用于传递 数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。JavaBean的属性是根据启动的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,至于你把它设置到那个变量上,则不用关心,如果方法名为getId,则属性名即为id.
JDK中提供了对JavaBean进行操作的一些API。这套API就称为内省。
spring集合类型的封装:
<property name="sets">
<set>
<value>value1</value>
<value>value2</value>
<value>vaule3</value>
<value>value4</value>
</set>
</property>
<property name="lists">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="maps">
<map>
<entry key="key1" value="value1" />
<entry key="key2" value="value2" />
</map>
</property>
<property name="props">
<props>
<prop key="p1">v1</prop>
</props>
</property>
spring依赖注入的实现:
private static class MyApplicationContect {
public static Object getBean(String name) throws Exception {
Map<String, String> nsMap = new HashMap<String, String>();
// 加入命名空间
nsMap.put("ns", "http://www.springframework.org/schema/beans");
// 创建beans/bean的路径
XPath xsub = document.createXPath("/ns:beans/ns:bean[@id='" + name + "']");
// 设置命名空间
xsub.setNamespaceURIs(nsMap);
Element ele = (Element)xsub.selectSingleNode(document);;
System.out.println(ele.attributeValue("class"));
Object retValue = Class.forName(ele.attributeValue("class")).newInstance();
for (Iterator<?> iter=ele.elementIterator("property"); iter.hasNext();) {
Element property = (Element)iter.next();
String propName = property.attributeValue("name");
if (property.attributeValue("value") != null) {
String strValue = property.attributeValue("value");
Class<?> paraType = retValue.getClass().getDeclaredField(propName).getType();
Object value = ConvertUtils.convert(strValue, paraType);
setProperty(retValue, propName, value);
//BeanUtils.setProperty(retValue, propName, strValue);
} else {
String ref = property.attributeValue("ref");
Object obj2 = getBean(ref);
setProperty(retValue, propName, obj2);
//BeanUtils.setProperty(retValue, propName, obj2);
}
}
return retValue;
}
private static void setProperty(Object object, String propertyName,
Object propertyValue) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor propertyX = new PropertyDescriptor(propertyName, object.getClass());
Method methodSetX = propertyX.getWriteMethod();
methodSetX.setAccessible(true);
methodSetX.invoke(object, propertyValue);
}
}
依赖注入共有三种:
使用构造器注入
使用属性setter方法注入
使用Field注入(用于注解注入)
注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。
手工装配依赖对象,在这种方式中又有两种编程方式。
1. 在xml配置中,通过在bean节点下配置(通过构造器注入,通过setter方法注入)
2. 在java代码中使用@Autowired或@Resource注解方式进行装配。但我们需要在xml配置文件中配置下面的
<context:annotation-config />这个配置方式注册了多个注释进行解析处理的处理器
:AutowireAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
注:@Resource注解在spring安装目录的lib/j2ee/common-annotations.jar
在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。
@Autowired
private PersonDao personDao; // 用于字段上
@Autowired
public void setOrderDao(OrderDao orderDao) { // 用于属性的setter方法上
}
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false,如果我们想使用按名称装配,可以结合@Qualified注解一起使用。如下:
Autowired @Qualifer(“personDaoBean”);
private PersonDao personDao;
@Resrouce注解和@Autowired一样,也可以标注在字段或属性的setter方法,但它默认按名称装配,名称可以通过@Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
@Resource(name=”personDaoBean”)
private PersonDao personDao // 用于字段上
注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时,@Resource注解会回退到按类型装配,但一旦指定了name属性,就只能按名称装配了。
自动装配的实现:<bean id=”” class=”” autowire=”byType”>
autowire属性取值如下:
.byType: 按类型装配,可以根据属性的类型,在容器中寻找跟类型匹配的bean,如果发现多个,那么就会抛出异常,如果没有找到,即属性值为null
.byName 按名称装配,可以根据属性的名称,在容器中寻找跟属性名相同的bean.如果没有找到,即属性值为null.
.constructor与byType的方式类似,不同之处在于它应用于构造器参数,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
autodeleted,通过bean类的自省机制(introspection来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。
spring2.5为我们引入了组件自动扫描机制,他可以在类路径下寻找标注了@Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理,它的作用和在xml文件中使用bean节点配置组件是一样的,要使用自动扫描机制,我们需要在配置文件中配置以下信息:
<context:component-scan base-package=”cn.itcast”>
其中base-package为需要扫描的包(含子包)
@Service用于标注业务层组件、@Controller用于标注控制层组件(如struts中的action)、@Repository用于标注数据访问组件,即DAO组件,而@Component泛指组件,当组件不好归类时,我们可以使用这个注解进行注册。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)