Spring的IOC的注解开发入门
目录
一、创建web项目,引入jar包
1.引入jar包
在Spring4的版本中,除了引入基本的开发包以外,还需要引入aop的包
引入的包:
2.引入Spring的配置文件
在src下创建applicationContext.xml,并引入约束。使用注解开发需要引入context约束。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
</beans>
3.创建接口和实现类
创建UserDao接口:
package com.rosinante.spring.demo1;
public interface UserDao {
public void save();
}
创建实现类:
package com.rosinante.spring.demo1;
/**
* 用户DAO的实现类
* @author Administrator
*
*/
public class UserDaoImpl implements UserDao{
public void save() {
// TODO Auto-generated method stub
System.out.println("DAO中保存用户的方法执行了...");
}
}
4.开启Spring的注解扫描
<!-- Spring的IOC注解 -->
<!-- 使用IOC的注解开发,配置扫描 -->
<context:component-scan base-package="com.rosinante.spring.demo1"></context:component-scan>
5.在类上添加注解
package com.rosinante.spring.demo1;
import org.springframework.stereotype.Component;
/**
* 用户DAO的实现类
* @author Administrator
*
*/
@Component(value="userDao") //相当于<bean id="userDao" class="com.rosinante.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao{
public void save() {
// TODO Auto-generated method stub
System.out.println("DAO中保存用户的方法执行了...");
}
}
6.编写测试类
package com.rosinante.spring.demo1;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Spring的IOC的注解开发的测试类
*/
public class SpringDemo1 {
@Test
//传统方式
public void demo1(){
UserDao userDao = new UserDaoImpl();
userDao.save();
}
@Test
//Spring的IOC的注解方式
public void demo2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao)applicationContext.getBean("userDao");
userDao.save();
}
}
运行结果如下:
7.注解方式设置属性的值
- 使用注解方式,可以没有set方法。
- 属性如果有set方法,需要将属性注入的注解添加到set方法
@Value("wangwu")
public void setName(String name) {
this.name = name;
}
- 属性如果没有set方法,需要将属性注入的注解添加属性上
@Value("wangwu")
private String name;
二、Spring的IOC的注解的详解
1.@Component:组件
- 修饰一个类,将这个类交给Spring管理,这个注解有三个衍生注解(功能类似)
- @Controller :web层
- @Service :service层
- @Repository :dao层
2.属性注入的注解
- 普通属性:
@Value :设置普通属性的值
- 对象类型属性:
@Autowired :设置对象类型的属性的值,但是按照类型完成属性注入
我们习惯按照名称完成属性注入:必须让@Autowired注解和@Qualifier 一起使用完成按照名称属性注入。
@Resource :完成对象类型的属性的注入,按照名称完成属性注入
举例:
创建一个UserService接口和它的实现类:
package com.rosinante.spring.demo1;
public interface UserService {
public void save();
}
package com.rosinante.spring.demo1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("userService") // <bean id="userService" class="">
public class UserServiceImpl implements UserService {
//注入DAO
@Autowired
@Qualifier(value="userDao")
private UserDao userDao;
public void save() {
// TODO Auto-generated method stub
System.out.println("UserService的save方法执行了...");
userDao.save();
}
}
编写测试方法:
@Test
public void demo3(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService)applicationContext.getBean("userService");
userService.save();
}
运行结果如下:
3.Bean的其他的注解
- 生命周期相关的注解(了解)
@PostConstruct :初始化方法
@PreDestory :销毁方法
编写一个CustomerService类以测试生命周期的相关注解:
package com.rosinante.spring.demo2;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Service;
@Service("customerService") //<bean id="" init-method="init" destory-method="destory"/>
public class CustomerService {
@PostConstruct //相当于init-method
public void init(){
System.out.println("CustomerService被初始化了...");
}
public void save(){
System.out.println("Service的save方法执行了...");
}
@PreDestroy //相当于destory-method
public void destory(){
System.out.println("CustomerService被销毁了...");
}
}
编写测试类:
package com.rosinante.spring.demo2;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo2 {
@Test
public void demo2(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerService customerService=(CustomerService)applicationContext.getBean("customerService");
System.out.println(customerService);
applicationContext.close();
}
}
运行结果如下:
- Bean的作用范围的注解
@Scope :作用范围
- singleton :默认单例
- prototype :多例
- request
- session
- globalsession
测试Bean的生命周期的相关注解:
@Scope默认是单例的:
在CustomerService类中加入@Scope注解:
@Service("customerService")
@Scope
public class CustomerService {
......
}
编写测试类,这里用两个bean来测试是否是单例:
public class SpringDemo2 {
@Test
public void demo2(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerService customerService1=(CustomerService)applicationContext.getBean("customerService");
System.out.println(customerService1);
CustomerService customerService2=(CustomerService)applicationContext.getBean("customerService");
System.out.println(customerService2);
applicationContext.close();
}
}
运行结果如下:
对象地址相同,说明默认是单例的。
如果将@Scope注解中设置为多例prototype:
@Service("customerService") //<bean id="" init-method="init" destory-method="destory"/>
@Scope("prototype")
public class CustomerService {
......
}
再次运行测试类:
可以发现对象地址不一样,说明有两个bean。并且没有被销毁,这是因为多例模式下是不会销毁bean的。
三、IOC的XML和注解开发比较
1.XML和注解的比较
适用场景:
- XML:可以适用任何场景;结构清晰,维护方便。
- 注解:有些地方用不了,这个类不是自己提供的;开发方便
2.XML和注解整合开发
- XML管理Bean,注解完成属性注入。
举例说明:
创建一个ProductService类、ProductDao类、OrderDao类:
package com.rosinante.spring.demo3;
import javax.annotation.Resource;
public class ProductService {
@Resource(name="productDao") //属性注入使用注解方式
private ProductDao productDao;
@Resource(name="orderDao")
private OrderDao orderDao;
public void save(){
System.out.println("ProductService save方法调用了...");
productDao.save();
orderDao.save();
}
}
package com.rosinante.spring.demo3;
public class ProductDao {
public void save(){
System.out.println("ProductDao save方法调用了...");
}
}
package com.rosinante.spring.demo3;
public class OrderDao {
public void save(){
System.out.println("OrderDao save方法调用了...");
}
}
配置bean:
这里可以关闭context:component-scan扫描,这是因为context:component-scan是扫描类上的注解,在没有扫描的情况下,使用属性注入的注解<context:annotation-config/>,可以直接使用@Resource、@Value、@Autowired、@Qulifier注解。
<!-- 在没有扫描的情况下,使用属性注入的注解 :@Resource。@Value。@Autowired。@Qulifier-->
<context:annotation-config />
<bean id="productService" class ="com.rosinante.spring.demo3.ProductService"></bean>
<bean id="productDao" class="com.rosinante.spring.demo3.ProductDao"></bean>
<bean id="orderDao" class="com.rosinante.spring.demo3.OrderDao"></bean>
编写测试类:
package com.rosinante.spring.demo3;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo3 {
@Test
public void demo1(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ProductService productService=(ProductService)applicationContext.getBean("productService");
productService.save();
}
}
运行结果如下: