Spring---IOC

xml配置方式实现IOC

使用IOC,要导入四个核心容器的包(Beans,Core,Context,SpEL)以及两个日志记录包,

Spring配置文件名为applicationContext.xml(可以自定义), 约束在spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html/xsd-configuration.html这个文件中找。

IOC和DI

         

/**
 * 接口与接口实现
 *
 */

public interface UserService {

	public void save1();
	public void save2();
}

public class UserServiceImpl implements UserService {

	private   String name;
	@Override
	public void save1() {
		System.out.println("UserService执行了");
	}
	
	@Override
	public void save2(){
		System.out.println("UserService执行了" + name);
	}

	public void setName(String name) {
		this.name = name;
	}
}

在applicationContext.xml中配置:

 class值为类的全路径(包名+类名)

<!--
	bean标签中还有个name属性  
	id:   使用了约束中的唯一约束。
		   里面不能出现特殊字符
	name:没有使用约束中的唯一约束(理论上可以出现重复的,但实际开发中不能出现)。
		 里面可以出现特殊字符。
-->	
	<bean id="UserService" class="demo01.UserServiceImpl">
		<property name="name" value="张三"/>	
	</bean>
    @Test
	/**
	 * Spring方式调用-----IOC
	 * 
	 * 	在配置文件中配置接口和接口的实现,然后在这里读取xml文件根据接口名字得到实现类
	 */
	public void test1(){
		//创建Spring 工厂
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		UserService userService = (UserService)applicationContext.getBean("UserService");
		userService.save1();
	}
@Test
	/**
	 * Spring--DI(依赖注入)
	 *  DI前提:实现IOC,即这个类要交给Spring去管理 
	 *  DI实例:接口的实现中有个name属性,可以在xml中用property标签配置它的值,实现类中必须
	 *          要有set方法。
	 *  
	 */
	public void test2(){
		//创建Spring 工厂
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		UserService userService = (UserService)applicationContext.getBean("UserService");
		userService.save2();
	}

applicationContext

 application是个接口,有FileSystemXmlApplicationContext,ClassPathXmlApplicationContext两个最终实现类                         

    

ClassPathXmlApplicationContext加载的是类路径下的配置文件,即src下的路径

 FileSystemXmlApplicationContext加载的是文件系统下的配置文件,即磁盘中的位置                                                 

@Test
public void test3(){
		//创建Spring 工厂
		ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\applicationContext.xml");	
		UserService userService = (UserService)applicationContext.getBean("UserService");
		System.out.println(22);
		userService.save1();
	}

Spring生命周期及Bean的作用范围

public interface CustomerDao {
	public void init();
	public void save();
	public void destory();
}

public class CustomerDaoImpl implements CustomerDao{
	public void init(){
		System.out.println("CustomerDaoImpl类开始初始化");
	}
	
	@Override
	public void save() {
		System.out.println("CustomerDaoImpl执行了");
	}
	
	public void destory(){
		System.out.println("CustomerDaoImpl类被销毁");
	}
}

 在xml中配置:

	<bean id="CustomerDao" class="demo02.CustomerDaoImpl" init-method="init" destroy-method="destory" scope=""></bean>

scope即作用范围的配置, 

 

 singleton:默认的,Spring会采用单例模式创建这个对象

prototype:多例模式创建(Struts2与Spring整合会用到)

request:应用在web项目中,Spring创建这个类以后,将这个类存到request范围中

session:应用在web项目中,Spring创建这个类以后,将这个类存到session范围中

@Test
	/**
	 * 生命周期配置
	 * 在配置文件的bean标签中添加 init-method="init" destroy-method="destory"来配置bean的生命周期(注意方法名不要括号)
	 *  然后在CustomerDaoImpl类中写这两个方法(要想执行销毁方法必须是单例,即没有在bean中配置scope="prototype")
	 */
	public void test1(){
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerDaoImpl customerDaoImpl = (CustomerDaoImpl)applicationContext.getBean("CustomerDao");
		customerDaoImpl.save();
		//只有执行了close()方法才会执行destory方法,close()方法是子类中方法所以用ClassPathXmlApplicationContext
		applicationContext.close();
	}
	
	@Test
	/**
	 * bean作用范围的配置
	 *   在配置文件的bean标签中添加scope属性,
	 *   singleton为单例,prototype为多例
	 */
	public void test2(){
		
	}

 Bean实例化的方式

/**
 * 无参数构造方法
 */
public class Bean1 {
	public Bean1() {
		super();
		System.out.println("Bean1的无参数的构造方法执行了...");
	}

}

/**
 * 静态工厂实例化
 */
public class Bean2 {

}
public class Bean2Factory {

	public static Bean2 createBean2(){
		System.out.println("Bean2Factory中方法执行了...");
		return new Bean2();
	}
}
/**
 * 实例工厂实例化
 */
public class Bean3 {

}
public class Bean3Factory {
	public Bean3 createBean3(){
		System.out.println("Bean3的实例工厂执行了...");
		return new Bean3();
	}
}

在xml中配置:

        <!-- 无参数构造方法 -->
	<bean id="bean1" class="demo03.Bean1"></bean>
	
	<!-- 静态工厂实例化 -->
	<bean id="bean2" class="demo03.Bean2Factory" factory-method="createBean2"/>
	
	<!-- 实例工厂实例化 -->
	<bean id="bean3Factory" class="demo03.Bean3Factory"></bean>
	<bean id="bean3"  factory-bean="bean3Factory" factory-method="createBean3"></bean>
        @Test
	public void test(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Bean1 bean1 = (Bean1) applicationContext.getBean("bean1");
	
		Bean2 bean2 = (Bean2) applicationContext.getBean("bean2");
		System.out.println(bean2);
	
		Bean3 bean3 = (Bean3) applicationContext.getBean("bean3");
		System.out.println(bean3);
	}

 属性注入,p名称空间,SpEL

构造方法方式的属性注入:

public class Car1 {
	private String name;
	private Double price;

	public Car1(String name, Double price) {
		super();
		this.name = name;
		this.price = price;
	}
	
	@Override
	public String toString() {
		return "Car [name=" + name + ", price=" + price + "]";
	}
}
        <!-- 构造方法方式 -->
	<bean id="Car1" class="demo04.Car1">
		<constructor-arg name="name" value="宝马"></constructor-arg>
		<constructor-arg name="price" value="800000"></constructor-arg>
	</bean>
public void demo1(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Car1 car1 = (Car1)applicationContext.getBean("Car1");
		System.out.println(car1);
	}

 set方法设置普通属性

public class Car2 {

	private String name;
	private Double price;

	public void setName(String name) {
		this.name = name;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Car [name=" + name + ", price=" + price + "]";
	}
}

                     普通设置方法:

	<bean id="Car2" class="demo04.Car2">
			<property name="name" value="奔驰"></property>
			<property name="price" value="1000000"></property>
		</bean>

                   使用p名称空间(2.5以后):

                                    约束中引入:xmlns:p="http://www.springframework.org/schema/p"

<bean id="Car2" class="demo04.Car2" p:name="奔驰" p:price="1000000">
		</bean>

                   使用SpEL(3.0以后):

                                  SpEL中都用value,不用ref,


	 <bean id="Car2" class="demo04.Car2">
		<property name="name" value="#{'奥迪'}"></property>
		<property name="price" value="#{500000}"></property>
	</bean>
public void demo2(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Car2 car2 = (Car2)applicationContext.getBean("Car2");
		System.out.println(car2);
	}

 set方法设置对象类型属性: 

public class Person {

	private String name;
	private Car2 car2;

	public void setName(String name) {
		this.name = name;
	}

	public void setCar2(Car2 car2) {
		this.car2 = car2;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", car2=" + car2 + "]";
	}
}

                   

                   普通设置方法:

	<bean id="Person" class="demo04.Person">
			<property name="name" value="张三"></property>
			<property name="car2" ref="Car2"></property>
		</bean>

                   使用p名称空间(2.5以后):

                                    约束中引入:xmlns:p="http://www.springframework.org/schema/p"

<bean id="Person" class="demo04.Person" p:name="张三" p:car2-ref="Car2">
		</bean> 

                   使用SpEL(3.0以后):

                                  SpEL中都用value,不用ref,


	<bean id="Person" class="demo04.Person">
		<property name="name" value="#{'张三'}"></property>
		<property name="car2" value="#{Car2}"></property>
	</bean>
public void demo(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person)applicationContext.getBean("Person");
		System.out.println(person);
	}

 集合属性注入

public class CollectionBean {

	private String[] strs;
	private List<String> list;
	private Set<String> set;
	private Map<String, String> map;

	public void setStrs(String[] strs) {
		this.strs = strs;
	}

	public void setList(List<String> list) {
		this.list = list;
	}

	public void setSet(Set<String> set) {
		this.set = set;
	}

	public void setMap(Map<String, String> map) {
		this.map = map;
	}

	@Override
	public String toString() {
		return "CollectionBean [strs=" + Arrays.toString(strs) + ", list=" + list + ", set=" + set + ", map=" + map
				+ "]";
	}
}

添加配置:

<bean id="CollectionBean" class="demo05.CollectionBean">
		<property name="strs">
			<list>
				<value>休斯顿</value>
				<value>爱琴海</value>
				<value>维也纳</value>
			</list>
		</property>
		
		<property name="list">
			<list>
				<value>北京市</value>
				<value>上海市</value>
				<value>西虹市</value>
			</list>
		</property>
		
		<property name="set">
			<set>
				<value>天津市</value>
				<value>重庆市</value>
				<value>深圳市</value>
			</set>
		</property>
		
		<property name="map">
			<map>
				<entry key="德国" value="不莱梅"/>
				<entry key="英国" value="英格兰"/>
				<entry key="美国" value="华盛顿"/>
			</map>
		</property>
	</bean>
public void test1(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		CollectionBean collectionBean = (CollectionBean) applicationContext.getBean("CollectionBean");
		System.out.println(collectionBean);
	}

注解方式实现IOC

还是在spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html/xsd-configuration.html这个文件中找到context的约束

注解开发相对xml开发多了一个aop的jar包

在xml中配置包扫描

<?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"> 
		
		<!-- 使用IOC的注解开发,配置组件扫描(哪些包下的类使用IOC的注解) -->
		<context:component-scan base-package="demo1,demo2"/>
</beans>

如果使用xml和注解混合开发,比如类是用的bean标签来交给Spring管理,上面没有@Component注解,但属性注入用的@Resource,@Value等注解时, 这时可以不用包扫描,因为扫描是为了扫描类上面的注释,就要加上下面的:

<?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 -->

		<!-- 使用IOC的注解开发,配置组件扫描(哪些包下的类使用IOC的注解) -->
		<!-- <context:component-scan base-package="demo1,demo2"/> -->
		
		<!-- 在没有扫描的情况下,使用属性注入的注解:@Resource,@Value -->
		<context:annotation-config/>
</beans>

类及属性注入的注解 

       @Component注解修饰一个类,表示将这个类交给Spring管理,它的衍生注解有@Controller,@Service,@Repository,相当于说 @Component是一个统称,Spring把它细分成三个注解,分别作用于:web层,service层,dao层。

         @Value注解设置普通属性

public interface UserDao {

	public void save();
}
@Component("UserDao")//相当于:<bean id="UserDao" class="demo1.UserDaoImpl"> </bean>

public class UserDaoImpl implements UserDao {

	//如果name属性没有set方法,@Value("张三")就写在这,如果有就写在set方法上
	private String name;

	@Value("张三")
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public void save() {
		System.out.println("dao中保存用户的方法执行了" + name);
	}
}
public void test(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao userDao = (UserDao)applicationContext.getBean("UserDao");
		userDao.save();
	}

      @Autowired用来设置对象类型的属性的值,但是是按照类型完成的注入,习惯按名称注入,所以加一个@Qualifier注解,后面的value值为别的类的注解的名称,必须一致

     @Autowired,@Qualifier这两个注解必须一起使用,Spring中还可以用@Resource完成对象类型注解,因为Spring实现了JSR-250规范

public interface UserService {

	public void save();
}
public class UserServiceImpl implements UserService {

	//注入Dao
	/**
	 * @Autowired
	 * @Qualifier(value="UserDao")//此处的value值必须与UserDao实现类的@Component注解值一致,
	 */
	
	@Resource(name="UserDao")
	private UserDao userDao;

	@Override
	public void save() {
		userDao.save();
	}

}
/**
	 * Spring的IOC对象属性注入注解,UserService中注入了UserDao
	 */
	public void test(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserService UserService = (UserService)applicationContext.getBean("UserService");
		UserService.save();
	}

生命周期及作用范围的注解

 @PostConstruct:初始化

@PreDestroy:销毁

@Scope:作用域

@Service("CustomerService")
@Scope("prototype")
public class CustomerService {

	@PostConstruct
	public void init(){
		System.out.println("CustomerService被初始化了");
	}
	
	public void save(){
		System.out.println("CustomerService的save方法执行了");
	}
	
	@PreDestroy
	public void destory(){
		System.out.println("CustomerService被销毁了");
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40605913/article/details/82011709
今日推荐