浅谈javaSpring框架(一)Spring的初体验


)

什么是Spring

Spring是一个开源的**控制反转(Inversion of Control,IOC)面向切面(Aspect Oriented Programming,AOP)**的容器框架,它的主要目的是简化企业开发。

IOC控制反转

什么是控制反转:Inversion of Control 就是应用本身不负责依赖对象的创建和维护,依赖对象的创建和维护由外部容器负责。这样控制权就由应用转移到外部容器,控制权的转移就是所谓的反转。

public class PersonbizImple {
     private PersonDao personDao;
      public void save(Person person){
            personDao.save(person);
     }
}

PersonDaoBean 是在应用内部创建及维护的。

依赖注入(Dependency Injection)

	biz中目前定义的只是dao的接口,那么外部容器创建完毕之后就要传递进来(构造方法,set),但是并不是人工传递调用,而是运行时动态的注入进来。

当我们把依赖对象交给外部容器负责创建,那么PersonServiceBean 类可以改成如下:

public class PersonbizImpl {
     private PersonDao personDao ;
    //通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。
     public PersonbizImpl(PersonDao personDao){
         this.personDao=personDao;
     }	
      public void save(Person person){
            personDao.save(person);
     }
}

所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。

为何要使用Spring

在项目中引入spring立即可以带来下面的好处:

  1. 降低组件之间的耦合度,实现软件各层之间的解耦。(只要知道接口不需要知道实现类)
  2. 可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务.也不需处理复杂的事务传播。
    (不需要知道什么时候事务begin,什么时候失败需要回滚)
  3. 容器提供单例模式支持,开发人员不再需要自己编写实现代码。
  4. 容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。
  5. 容器提供的众多辅作类,使用这些类能够加快应用的开发,如: JdbcTemplate、 HibernateTemplate。
  6. Spring对于主流的应用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,这样更便于应用的开发。

轻量级与重量级概念的划分

经常会有同学问到spring属于轻量级框架,还是重量框架?其实划分一个应用是否属于轻量级还是重量级,主要看它使用了多少服务.使用的服务越多,容器要为普通java对象做的工作就越多,必然会影响到应用的发布时间或者是运行性能.

在这里插入图片描述
对于spring容器,它提供了很多服务,但这些服务并不是默认为应用打开的,应用需要某种服务,还需要指明使用该服务,如果应用使用的服务很少,如:只使用了spring核心服务,那么我们可以认为此时应用属于轻量级的,如果应用使用了spring提供的大部分服务,这时应用就属于重量级

如何实例化spring容器

实例化Spring容器常用的两种方式:
方法一:

在类路径下寻找配置文件来实例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});

方法二:

在文件系统路径下寻找配置文件来实例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring的配置文件可以指定多个,可以通过String数组传入。

从spring容器中得到bean

当spring容器启动后,因为spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。从容器获取bean对象的代码如下:

ApplicationContext ctx = new ClassPathXmlApplicationContext(“beans.xml”);
OrderService service = (OrderService)ctx.getBean("personService");

三种实例化bean的方式

1.使用类构造器实例化
<bean id=“orderService” class=“cn.itcast.OrderServiceBean”/>实例化无参构造函数
2.使用静态工厂方法实例化

<bean id="personService" class="cn.itcast.service.OrderFactory" factory-method="createOrder"/>
public class OrderFactory {
	public static OrderServiceBean createOrder(){
		return new OrderServiceBean();
	}
}

3.使用实例工厂方法实例化:

<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/>
public class OrderFactory {
	public OrderServiceBean createOrder(){
		return new OrderServiceBean();
	}
}

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-lazy-init=“true“,如下:

<beans default-lazy-init="true...>

.prototype
每次从容器获取bean都是新的对象。
.request
.session
.global session

.request
表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
.session
表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
.globalSession
不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session
的概念,它被所有构成某个portlet web应用的各种不同的portlet所共享。
以上3种均基于web的Spring ApplicationContext(WEB项目)情形下有效

Bean的初始化方法和销毁方法

<bean id="xxx" class=“biz.OrderServiceBean" init-method="init" destroy-method="close"/>

  public void init() {
      System.out.println(“已经初始化了”);
  } 
  public void close() {
      System.out.println(“被销毁了”);
  }
  
  AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
  PersonService person = (PersonService)ctx.getBean("personServiceBean");
  ctx.close();

注意:必须是无参的方法,可以有返回值。

注入依赖对象

基本类型对象注入:

  <bean id="orderService" class="cn.itcast.service.OrderServiceBean">
	<constructor-arg index=0” type=“java.lang.String” value=“xxx”/>//构造器注入
	<property name=“name” value=“zhao/>//属性setter方法注入
    </bean>

注入其他bean:表示null值
方式一

<bean id="orderDao" class="cn.itcast.service.OrderDaoBean"/>
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<property name="orderDao" ref="orderDao"/>
</bean>

方式二(使用内部bean,但该bean不能被其他bean引用) 不推荐使用

  <bean id="orderService" class="cn.itcast.service.OrderServiceBean">
	<property name="orderDao">
                                   <!--没有id(name)属性,所以不能被其它引用-->
		<bean class=“cn.itcast.service.OrderDaoBean”/>
	</property>
    </bean>

注入依赖对象之集合类型的装配

public class OrderServiceBean {
	private Set<String> sets = new HashSet<String>();
	private List<String> lists = new ArrayList<String>();
	private Properties properties = new Properties();
	private Map<String, String> maps = 
                                               new HashMap<String, String>();
        ....//这里省略属性的getter和setter方法
}
<bean id="order" class="cn.itcast.service.OrderServiceBean">
    <property name="lists">
          <list>
	<value>pkbest</value>
         </list>
      </property>		
      <property name="sets">
         <set>
            <value>pkbest</value>
        </set>
      </property>		
     <property name="maps">
        <map>
            <entry key=“pkbest" value="28"/>
       </map>
     </property>		
     <property name="properties">
        <props>
	<prop key=“pk">best</prop>
       </props>
      </property>
</bean>

依赖注入的常用方法

1. 使用构造器注入
2. 使用属性setter方法注入
3. 使用Field注入

(用于注解方式,只需要定义属性,不需要get,set但是需要用注解,叫做自动装配)

依赖注入----手工装配

方法1. 在xml配置文件中,通过在bean节点下配置,如

 <bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<constructor-arg index=0” type=“java.lang.String” value=“xxx”/>//构造器注入
<property name=“name” value=“zhao/>//属性setter方法注入
 </bean>

方法2:在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@Autowired
private PersonDao personDao;//用于字段上
@Autowired
public void setOrderDao(OrderDao orderDao) {//用于setter方法上
this.orderDao = orderDao;
}
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在

@Resource注解和@Autowired一样,也可以标注在字段或setter方法上,但它默认按名称装配。名称可以通过@Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在setter方法上,即默认取bean名称寻找依赖对象。
@Resource(name=“personDaoBean”)
private PersonDao personDao;//用于字段上

注意:如果没有指定name属性,并且按照默认的名称找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。

通过在classpath自动扫描方式把组件纳入spring容器中管理

前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,通常会有上百个组件,如果这些这组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找及维护起来也不太方便。spring为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:
<context:component-scan base-package=“cn.itcast”/>
其中base-package为需要扫描的包(含子包)。
@Service用于标注业务层组件(biz.impl)、 @Controller用于标注控制层组件(如struts中的action)、@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Scope用于指定scope作用域的(用在类上) @PostConstruct用于指定初始化方法(用在方法上)
@PreDestory用于指定销毁方法(用在方法上)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值