Spring的工厂类

image.png

  • FileSystemXmlApplicationContext是加载文件路径下的配置文件
  • ClassPathXmlApplicationContext是加载类路径下的配置文件

XML方式

代码下载: git@gitee.com:chenxiaonian/spring_ioc.git

Bean的实例化的三种方式

  1. 采用无参数的构造方法的方式:

src/main/java/com/song/ioc/demo2/Bean1.java

  1. package com.song.ioc.demo2;
  2. /**
  3. * Bean的实例化的三种方式:采用无参数的构造方法的方式
  4. */
  5. public class Bean1 {
  6. public Bean1(){
  7. System.out.println("Bean1被实例化了...");
  8. }
  9. }

rc/main/resources/applicationContext.xml

    <!-- 第一种:无参构造器的方式 -->
    <bean id="bean1" class="com.song.ioc.demo2.Bean1" />
  1. 静态工厂实例化方式:

src/main/java/com/song/ioc/demo2/Bean2.java

package com.song.ioc.demo2;

/**
 * Bean的实例化的三种方式:静态工厂实例化方式
 */
public class Bean2 {
}

src/main/java/com/song/ioc/demo2/Bean2Factory.java

package com.song.ioc.demo2;

/**
 * Bean2的静态工厂
 */
public class Bean2Factory {
    public static Bean2 createBean2(){
        System.out.println("Bean2Factory的方法已经执行了...");
        return new Bean2();
    }
}

rc/main/resources/applicationContext.xml

    <!-- 第二种:静态工厂的方式 -->
    <bean id="bean2" class="com.song.ioc.demo2.Bean2Factory" factory-method="createBean2"/>
  1. 实例工厂实例化方式:

src/main/java/com/song/ioc/demo2/Bean3.java

package com.song.ioc.demo2;

/**
 * Bean的实例化的三种方式:实例工厂实例化方式
 */
public class Bean3 {
}

src/main/java/com/song/ioc/demo2/Bean3Factory.java

package com.song.ioc.demo2;

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

src/main/resources/applicationContext.xml

    <!-- 第三种:实例工厂的方式 -->
    <bean id="bean3Factory" class="com.song.ioc.demo2.Bean3Factory"/>
    <bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>

测试:

package com.song.ioc.demo2;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo2Testor {
    @Test
    public void demo1(){
        // 创建工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类的实例
        Bean1 bean1 = (Bean1) applicationContext.getBean("bean1");
    }

    @Test
    public void demo2(){
        // 创建工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类的实例
        Bean2 bean2 = (Bean2) applicationContext.getBean("bean2");
    }

    @Test
    public void demo3(){
        // 创建工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类的实例
        Bean3 bean3 = (Bean3) applicationContext.getBean("bean3");
    }
}

Bean的常用配置**

  • id和name

一般情况下,装配一个Bean时,通过制定一个id属性作为Bean的名称
id属性在IOC容器中必须是唯一的
如果Bean的名称中含有特殊字符,就需要使用name属性

  • clsss属性:设置一个类的完全路径名称,主要作用是IOC容器生成类的实例
  • scope属性:设置Bean的作用域

默认值:singleton
image.png
**
src/main/java/com/song/ioc/demo3/Person.java

package com.song.ioc.demo3;

public class Person {
}
  1. scope设置为singleton的情况

src/main/resources/applicationContext.xml

<!--    Bean的作用范围-->
<bean id="person" class="com.song.ioc.demo3.Person"></bean>

src/test/java/com/song/ioc/demo3/Demo3Testor.java

package com.song.ioc.demo3;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Bean的作用范围测试
 */
public class Demo3Testor {
    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person1 = (Person) applicationContext.getBean("person");
        Person person2 = (Person) applicationContext.getBean("person");

        System.out.println(person1);    // com.song.ioc.demo3.Person@815b41f
        System.out.println(person2);    // com.song.ioc.demo3.Person@815b41f
    }
}
  1. scope设置为prototype的情况

src/main/resources/applicationContext.xml

<!--    Bean的作用范围-->
<bean id="person" class="com.song.ioc.demo3.Person" scope="prototype"></bean>

src/test/java/com/song/ioc/demo3/Demo3Testor.java

package com.song.ioc.demo3;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Bean的作用范围测试
 */
public class Demo3Testor {
    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person1 = (Person) applicationContext.getBean("person");
        Person person2 = (Person) applicationContext.getBean("person");

        System.out.println(person1);    // com.song.ioc.demo3.Person@7dcf94f8
        System.out.println(person2);    // com.song.ioc.demo3.Person@229f66ed
    }
}

Bean的生命周期的配置

Spring初始化bean或销毁bean时,有时需要做一些处理工作,因此spring可以在创建和销毁bean的时候调用bean的两个生命周期方法。
image.png

src/main/java/com/song/ioc/demo3/Man.java

package com.song.ioc.demo3;

public class Man {
    public Man(){
        System.out.println("Man被实例化了...");
    }

    public void setup(){
        System.out.println("Man被实例化了...");
    }

    public void teardown(){
        System.out.println("Man被销毁了");
    }
}

src/main/resources/applicationContext.xml

<bean id="man" class="com.song.ioc.demo3.Man" init-method="setup" destroy-method="teardown"/>

src/test/java/com/song/ioc/demo3/Demo3Testor.java

package com.song.ioc.demo3;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Bean的作用范围测试
 */
public class Demo3Testor {

    @Test
    public void test2() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Man man = (Man) applicationContext.getBean("man");
        applicationContext.close();
    }
}

运行结果:
Man被实例化了…
Man被实例化了…
Man被销毁了

Bean的生命周期的完整过程

image.png

image.png
image.png

第五步和第八步很关键,可以增强bean

src/main/java/com/song/ioc/demo3/Man.java

package com.song.ioc.demo3;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class Man implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
    private String name;

    public Man(){
        System.out.println("第一步:初始化");
    }

    public void setName(String name){
        System.out.println("第二步:设置属性");
        this.name = name;
    }

    public void setup(){
        System.out.println("第七步:Man被实例化了");
    }

    public void teardown(){
        System.out.println("第十一步:Man被销毁了");
    }

    public void run(){
        System.out.println("第九步:执行业务方法");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("第三步:设置Bean的名称"+name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("第四步:了解工厂信息");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第六步:属性设置后");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("第十步:执行Spring的销毁方法");
    }
}

src/main/java/com/song/ioc/demo3/MyBeanPostProcessor.java

package com.song.ioc.demo3;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第五步:初始化前方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第八步:初始化后方法");
        return bean;
    }
}

src/main/resources/applicationContext.xml

    <bean id="man" class="com.song.ioc.demo3.Man" init-method="setup" destroy-method="teardown">
        <property name="name" value="张三"/>
    </bean>
    <bean class="com.song.ioc.demo3.MyBeanPostProcessor"/>

src/test/java/com/song/ioc/demo3/Demo3Testor.java


    @Test
    public void test2() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Man man = (Man) applicationContext.getBean("man");
        man.run();
        applicationContext.close();
    }

BeanPostProcessor的作用

可以设置代理类,增强类的方法。比如,在保存用户之前,校验用户权限

src/main/java/com/song/ioc/demo3/UserDao.java

package com.song.ioc.demo3;

public interface UserDao {
    public void findAll();

    public void save();

    public void update();

    public void delete();
}

src/main/java/com/song/ioc/demo3/UserDaoImpl.java

package com.song.ioc.demo3;

public class UserDaoImpl implements UserDao{
    @Override
    public void findAll() {
        System.out.println("查询用户");
    }

    @Override
    public void save() {
        System.out.println("保存用户");
    }

    @Override
    public void update() {
        System.out.println("修改用户");
    }

    @Override
    public void delete() {
        System.out.println("删除用户");
    }
}

src/main/java/com/song/ioc/demo3/MyBeanPostProcessor.java

package com.song.ioc.demo3;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第五步:初始化前方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第八步:初始化后方法");

        // 如果是"userDao"类,就返回增强的代理类
        if ("userDao".equals(beanName)) {
            Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    // 如果是save方法,就先做权限校验
                    if ("save".equals(method.getName())) {
                        System.out.println("=== 权限校验 ===");
                        return method.invoke(bean, args);
                    }
                    return method.invoke(bean, args);
                }
            });
            return proxy;
        } else {
            return bean;
        }
    }
}

src/main/resources/applicationContext.xml

<bean class="com.song.ioc.demo3.MyBeanPostProcessor"/>
<bean id="userDao" class="com.song.ioc.demo3.UserDaoImpl"/>

src/test/java/com/song/ioc/demo3/Demo3Testor.java

    @Test
    public void test3() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) applicationContext.getBean("userDao");

        userDao.findAll();
        userDao.save();
        userDao.update();
        userDao.delete();
    }

运行结果:
第五步:初始化前方法
第八步:初始化后方法
查询用户
=== 权限校验 ===
保存用户
修改用户
删除用户

Spring的属性注入- 构造函数

  • 通过构造方法注入Bean的属性值或依赖的对象,它保证了Bean实例在实例化后就可以使用
  • 构造器注入在元素里声明的属性

src/main/java/com/song/ioc/demo4/User.java

package com.song.ioc.demo4;

public class User {
    private String name;
    private Integer age;

    public User(String name, Integer age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

src/main/resources/applicationContext.xml

    <!--  Bean的构造方法的属性注入  -->
    <bean id="user" class="com.song.ioc.demo4.User">
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="23"/>
    </bean

src/test/java/com/song/ioc/demo4/Demo4Testor.java

package com.song.ioc.demo4;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo4Testor {
    @Test
    public void test1() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) applicationContext.getBean("user");
        System.out.println(user);
    }
}

运行结果:User{name=’张三’, age=23}

Spring的属性注入- 属性setter方法

  • 使用set方法注入,在Spring配置文件中,通过设置注入的属性

src/main/java/com/song/ioc/demo4/Person.java

package com.song.ioc.demo4;

public class Person {
    private String name;
    private Integer age;
    private Cat cat;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", cat=" + cat +
                '}';
    }
}

src/main/java/com/song/ioc/demo4/Cat.java

package com.song.ioc.demo4;

public class Cat {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}

src/main/resources/applicationContext.xml

    <bean id="person" class="com.song.ioc.demo4.Person">
        <property name="name" value="李四"/>
        <property name="age" value="32"/>
        <property name="cat" ref="cat"/>
    </bean>

    <bean id="cat" class="com.song.ioc.demo4.Cat">
        <property name="name" value="ketty"/>
    </bean>

src/test/java/com/song/ioc/demo4/Demo4Testor.java

    @Test
    public void test2() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
    }

运行结果:
Person{name=’李四’, age=32, cat=Cat{name=’ketty’}}

Spring的属性注入- p名称空间

为了简化XML文件配置,Spring从2.5开始引入一个新的p名称空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--    Bean的p名称空间的属性注入-->
    <bean id="person" class="com.song.ioc.demo4.Person" p:name="大黄" p:age="34" p:cat-ref="cat"/>
    <bean id="cat" class="com.song.ioc.demo4.Cat" p:name="小黄"/>

</beans>

Spring的属性注入- SpEL的属性注入

image.png

src/main/java/com/song/ioc/demo4/Category.java

package com.song.ioc.demo4;

public class Category {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "category{" +
                "name='" + name + '\'' +
                '}';
    }
}

src/main/java/com/song/ioc/demo4/Product.java

package com.song.ioc.demo4;

public class Product {
    private String name;
    private Double price;
    private Category category;

    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", category=" + category +
                '}';
    }

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

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

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }
}

src/main/java/com/song/ioc/demo4/ProductInfo.java

package com.song.ioc.demo4;

public class ProductInfo {
    public Double calculatePrice(){
        return Math.random() * 199;
    }
}

src/main/resources/applicationContext.xml

    <!--    Bean的SpEL的属性注入-->
    <bean id="category" class="com.song.ioc.demo4.Category">
        <property name="name" value="#{'服装'}"/>
    </bean>

    <bean id="productInfo" class="com.song.ioc.demo4.ProductInfo"/>

    <bean id="product" class="com.song.ioc.demo4.Product">
        <property name="name" value="#{'男装'}"/>
        <property name="price" value="#{productInfo.calculatePrice()}"/>
        <property name="category" value="#{category}"/>
    </bean>

src/test/java/com/song/ioc/demo4/Demo4Testor.java

    @Test
    public void test3() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Product product = (Product) applicationContext.getBean("product");
        System.out.println(product);
    }

运行结果:
Product{name=’男装’, price=98.97027483577997, category=category{name=’服装’}}

Spring的属性注入- 复杂类型的属性注入

  • 数组类型的属性注入
  • List集合类型的属性注入
  • Set集合类型的属性注入
  • Map集合类型的属性注入
  • Properties类型的属性注入

src/main/java/com/song/ioc/demo5/collectionBean.java

package com.song.ioc.demo5;

import java.util.*;

public class CollectionBean {
    private String[] arrs;
    private List<String> list;
    private Set<String> set;
    private Map<String, Integer> map;
    private Properties properties;

    public String[] getArrs() {
        return arrs;
    }

    public void setArrs(String[] arrs) {
        this.arrs = arrs;
    }

    public List<String> getList() {
        return list;
    }

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

    public Set<String> getSet() {
        return set;
    }

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

    public Map<String, Integer> getMap() {
        return map;
    }

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

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "arrs=" + Arrays.toString(arrs) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}

src/main/resources/applicationContext.xml


    <!--    集合类型的属性注入-->
    <bean id="collectionBean" class="com.song.ioc.demo5.CollectionBean">
        <!--        数组类型-->
        <property name="arrs">
            <list>
                <value>arrs-1</value>
                <value>arrs-2</value>
                <value>arrs-3</value>
            </list>
        </property>
        <!--        List集合的属性注入-->
        <property name="list">
            <list>
                <value>list-1</value>
                <value>list-2</value>
                <value>list-3</value>
            </list>
        </property>
        <!--    Set集合的属性注入-->
        <property name="set">
            <set>
                <value>set-1</value>
                <value>set-2</value>
                <value>set-3</value>
            </set>
        </property>
        <!--        Map集合的属性注入-->
        <property name="map">
            <map>
                <entry key="key-1" value="111"/>
                <entry key="key-2" value="222"/>
                <entry key="key-3" value="333"/>
            </map>
        </property>
        <!--        Properties的属性注入-->
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="password">1234</prop>
            </props>
        </property>
    </bean

src/test/java/com/song/ioc/demo5/Demo5Testor.java

package com.song.ioc.demo5;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo5Testor {
    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        CollectionBean collectionBean = (CollectionBean)applicationContext.getBean("collectionBean");
        System.out.println(collectionBean);
    }
}

运行结果:
CollectionBean{arrs=[arrs-1, arrs-2, arrs-3], list=[list-1, list-2, list-3], set=[set-1, set-2, set-3], map={key-1=111, key-2=222, key-3=333}, properties={password=1234, username=root}}

注解方式

代码下载: git clone git@gitee.com:chenxiaonian/spring_ioc_annotation.git

  • Spring2.5 引入使用注解去定义Bean

@Component 描述Spring框架中Bean

  • 除了@Component外,Spring提供了3个功能基本和@Component等效的注解

Repository 用于对DAO实现类进行标注
@Service 用于对Service实现类进行标注
@Controller 用于对Controller实现类进行标注

Bean的管理

src/main/java/com/song/ioc/demo1/UserService.java

package com.song.ioc.demo1;

import org.springframework.stereotype.Component;

/**
 * Spring的Bean管理的注解方式:
 * 传统方式需要去XML中配置<bean id="" class=""></bean>
 */
@Component("userService")
public class UserService {
    public String sayHello(String name){
        return "hello" + name;
    }
}

src/main/resources/applicationContext.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">

    <!--    开启注解扫描-->
    <context:component-scan base-package="com.song.ioc"/>

</beans>

src/test/java/com/song/ioc/demo1/Demo1Testor.java

package com.song.ioc.demo1;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo1Testor {
    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService)applicationContext.getBean("userService");

        String s = userService.sayHello("张三");
        System.out.println(s);
    }
}

运行结果:hello张三

属性注入的注解

image.png
image.png

@Resource 相当于 @AutoWired + @Qualifier

src/main/java/com/song/ioc/demo1/UserService.java

package com.song.ioc.demo1;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Spring的Bean管理的注解方式:
 * 传统方式需要去XML中配置<bean id="" class=""></bean>
 */
@Service("userService")
public class UserService {
    @Value("米饭")
    private String food;

//    @Autowired
//    @Qualifier("userDao")
    @Resource(name = "userDao")
    private UserDao userDao;

    public String sayHello(String name) {
        return "hello" + name;
    }

    public void eat() {
        System.out.println("eat" + food);
    }

    public void save(){
        System.out.println("Service中保存用户。。。");
        userDao.save();
    }
}

src/main/java/com/song/ioc/demo1/UserDao.java

package com.song.ioc.demo1;

import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDao {
    public void save(){
        System.out.println("DAO中保存用户。。。");
    }
}

src/test/java/com/song/ioc/demo1/Demo1Testor.java

package com.song.ioc.demo1;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo1Testor {
    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService)applicationContext.getBean("userService");

        String s = userService.sayHello("张三");
        System.out.println(s);
    }

    @Test
    public void test2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService)applicationContext.getBean("userService");
        userService.eat();
    }

    @Test
    public void test3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService)applicationContext.getBean("userService");
        userService.save();
    }
}

test2的运行结果:

eat米饭

test3的运行结果:

Service中保存用户。。。
DAO中保存用户。。。

其他注解

image.png

src/main/java/com/song/ioc/demo2/Bean1.java

package com.song.ioc.demo2;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component("bean1")
public class Bean1 {
    @PostConstruct
    public void init() {
        System.out.println("initBean");
    }

    public void say() {
        System.out.println("say");
    }

    @PreDestroy
    public void destory() {
        System.out.println("destoryBean");
    }
}

src/main/java/com/song/ioc/demo2/Bean2.java

package com.song.ioc.demo2;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("bean2")
@Scope("prototype")
public class Bean2 {

}

src/test/java/com/song/ioc/demo2/Demo2Testor.java

package com.song.ioc.demo2;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo2Testor {
    @Test
    public void test1(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");
        bean1.say();
        applicationContext.close();
    }

    @Test
    public void test2(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        Bean2 bean21 = (Bean2) applicationContext.getBean("bean2");
        Bean2 bean22 = (Bean2) applicationContext.getBean("bean2");

        System.out.println(bean21 == bean22);
    }
}

test1运行结果:

initBean
say
destoryBean

test2运行结果:

initBean
false    // Bean2设置了 @Scope("prototype")
true    // Bean2不设置 @Scope("prototype")

Spring的XML和注解整合开发

image.png

src/main/java/com/song/ioc/demo3/CategoryDao.java

package com.song.ioc.demo3;

public class CategoryDao {
    public void save(){
        System.out.println("CategoryDao的save方法执行了。。。");
    }
}

src/main/java/com/song/ioc/demo3/ProductDao.java

package com.song.ioc.demo3;

public class ProductDao {
    public void save(){
        System.out.println("ProductDao的save方法执行了。。。");
    }
}

src/main/java/com/song/ioc/demo3/ProductService.java

package com.song.ioc.demo3;

import javax.annotation.Resource;

public class ProductService {
    @Resource(name = "categoryDao")
    private CategoryDao categoryDao;

    @Resource(name = "productDao")
    private ProductDao productDao;

    public void save(){
        System.out.println("ProductService的save方法执行了");
        categoryDao.save();
        productDao.save();
    }
}

src/main/resources/applicationContext.xml

    <!--    可以使用属性输入的注解-->
    <context:annotation-config></context:annotation-config>
    <bean id="productService" class="com.song.ioc.demo3.ProductService"/>
    <bean id="productDao" class="com.song.ioc.demo3.ProductDao"/>
    <bean id="categoryDao" class="com.song.ioc.demo3.CategoryDao"/>

src/test/java/com/song/ioc/demo3/Demo3Testor.java

package com.song.ioc.demo3;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo3Testor {
    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        ProductService productService = (ProductService)applicationContext.getBean("productService");
        productService.save();
    }
}

运行结果:
ProductService的save方法执行了
CategoryDao的save方法执行了。。。
ProductDao的save方法执行了。。。