Spring_IOC 之 bean 的配置

1.Spring之Bean创建三种方式:
(1) 调用构造器创建Bean
     调用构造方法创建Bean是最常用的一种情况Spring容器通过new关键字调用构造器来创建Bean实例,通过class属性指定Bean实例的实现类,也就是说,如果使用构造器创建Bean方法,则<bean/>元素必须指定class属性,其实Spring容器也就是相当于通过实现类new了一个Bean实例。调用构造方法创建Bean实例,通过名字也可以看出,我们需要为该Bean类提供无参数的构造器。下面是一个通过构造方法创建Bean的最简单实例。
     ① Bean实例实现类 Person.java
package com.atguigu.spring.pojo;
public class Person {
      private String name;
         public Person()   {
             System.out.println("Spring容器开始通过无参构造器创建Bean实例------------");
         }
         public void setName(String name){
             this.name = name;
         }
         public void input(){
             System.out.println("欢迎来到我的博客:"+name);
         }
}
     因为是通过构造函数创建Bean,因此我们需要提供无参数构造函数,另外我们定义了一个name属性,并提供了setter方法,Spring容器通过该方法为name属性注入参数。
     ② 配置文件beans.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"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 指定class属性,通过构造方法创建Bean实例 -->
    <bean id="person" class="com.atguigu.spring.pojo.Person">
      <!-- 通过调用setName方法,将VipMao作为参数传入 -->
      <property name="name" value="Luo"></property>
    </bean>
</beans>
     配置文件中,通过<bean>元素的id属性指定该bean的唯一名称,class属性指定该bean的实现类,可以理解成Spring容器就是通过该实现类new了一个Bean。通过<property>标签的name属性和value属性指定了:调用setName方法,将VipMao作为参数注入。
     ③ 测试类 PersonTest.java
package com.atguigu.spring.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.atguigu.spring.pojo.Person;

public class PersonTest {
     public static void main(String[]args){ 
        //创建Spring容器 
        ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml"); 
        //通过getBean()方法获取Bean实例 
        Person person=(Person)ctx.getBean("person"); 
        person.input(); 
      } 
}
     ④运行结果

     通过静态工厂创建Bean,是不是听着高大上了?顾名思义,咱们把创建Bean的任务交给了静态工厂,而不是构造函数,这个静态工厂就是一个Java类,那么使用静态工厂创建Bean咱们又需要添加哪些属性呢?我们同样需要<bean/>元素内添加class属性,上面也说了,静态工厂是一个Java类,那么该class属性指定的就是该工厂的实现类,而不再是Bean的实现类,告诉Spring这个Bean应该由哪个静态工厂创建,另外我们还需要添加factory-method属性来指定由工厂的哪个方法来创建Bean实例,因此使用静态工厂方法创建Bean实例需要为<bean/>元素指定如下属性:(2) 调用静态工厂方法创建Bean
class:指定静态工厂的实现类,告诉Spring该Bean实例应该由哪个静态工厂创建(指定工厂地址)
factory-method:指定由静态工厂的哪个方法创建该Bean实例(指定由工厂的哪个车间创建Bean) , 如果静态工厂方法需要参数,则使用<constructor-arg.../>元素传入 。
(3) 调用实例工厂方法创建Bean
      其实调用实例工厂创建Bean和调用静态工厂创建Bean的区别就在于,调用实例工厂将工厂单独拿了出来(先实例化工厂)创建一个工厂Bean,通过工厂<bean>的class属性指定工厂的实现类,然后再需要创建其他Bean时,只需要在该<bean/>元素添加factory-bean、factory-method指定该Bean是有哪个实例工厂的哪个方法创建就可以了,放在现实生活中就是:我们先找一个地方创建一个工厂,id指定工厂注册名字(xxx有限公司),class指定公司所在地,工厂里面有车间(创造其他Bean的方法),那好有了工厂我们再需要创建其他Bean时,只需要指定这个Bean是由,哪个工厂的哪个车间创建的即可,也就是只需要在该<bean/>元素添加factory-bean、factory-method属性即可。

2.Spring容器对Bean组件的管理
          scope="singleton"    单例的。默认值
          scope="prototype"   多例的。
          scope= "session": 一次会话。
          scope= "request": 一次请求。

3.获取Bean的方式
      根据id获取Bean对象:
          Student student = (Student)ioc.getBean("student");
      根据类型获取Bean对象: 根据类型查找Bean,必须保证只能查找到一个Bean对象,如果有多个会报错。
          Student student = ioc.getBean(Student.class);

4.bean的生命周期:
     ① 定义
     ② 初始化
     ③  使用
     ④ 销毁
     说明:默认配置全局的初始化,销毁方法,如果不设置,系统会自动加上。
5.Spring_IOC之XML自动装配:
(1) 在beans.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"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

     <!--
           autowire : 自动装配
                byName : 表示根据属性名称(不是成员变量名称)来查找关联的Bean对象,然后,注入到当前Bean对象中,进行属性赋值
                byType : 表示根据属性类型来查找关联的Bean对象,如果存在,就注入到当前Bean对象中,进行属性赋值
                     如果查找到多个相同类型的对象,属性为单数类型,注入失败;可以采用复数类型(数组或集合(泛型))接收多个对象;
      -->

     <bean id="userService2" class="com.pers.spring.component.UserServiceImpl" autowire="byType">
           <!-- <property name="userDao" ref="userDao2"></property> -->
     </bean>

 <!--      <bean id="userDao2" class="com.pers.spring.component.UserDaoImpl"></bean>
           <bean id="userDao3" class="com.pers.spring.component.UserDaoImpl"></bean>
 -->
</beans>
(2) 在UserServiceImpl中:
package com.pers.spring.component;
import java.util.List;
public class UserServiceImpl implements UserService{
     private List<UserDaoImpl> userDao ;
     private String message ;
     public void setUserDao(List<UserDaoImpl> userDao) {
           this.userDao = userDao;
     }
     public void saveUser(){
           userDao.get(0).save();
     }

     public String getMessage() {
           return message;
     }
     public void setMessage(String message) {
           this.message = message;
     }
     public List<UserDaoImpl> getUserDao() {
           return userDao;
     }
}
(3) 在测试类中
package junit.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.pers.spring.component.UserService;
public class TestIOC_Autowire {
     ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
     @Test
     public void testAutowire() {
           UserService userService = (UserService)ioc.getBean("userService2");
           System.out.println(userService);
     }
}
6.Spring_IOC的Annotation完成自动装配:
(1) XML和Annotation两种开发方式
① XML :
<bean id="student" class="com.atguigu.spring.bean.Student" scope="prototype"></bean>
② Annotation :
@Component
@Scope("prototype") //多例创建对象
public class Student(){}
(2) Spring框架提供了分层注解,来声明各个层中的Bean对象
@Controller   用于表现层
@Service   用于服务层
@Repository   用于持久化层
@Component  用于哪些不太明确属于某个层的Bean对象的声明,比较通用,可以代替分层注解
(3) 使用注解声明Bean对象的id,默认是类的名称首字母小写
类名  Bean的id名称
UserAction  userAction
UserServiceImpl  userServiceImpl
UserDaoImpl  userDaoImpl
(4) 配置扫描的包 <!-- 设置扫描的包 -->
<context:component-scan base-package="com.pers.spring.*"/>
(5) 需要拷贝AOP的包:
spring-aop-4.0.0.RELEASE.jar
(6) 设置扫描的包,包含或者不包含:
<?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-4.0.xsd">

     <!-- 设置扫描的包 -->
     <context:component-scan base-package="com.atguigu.spring.*"/>

     <!--使用context:include-filter指定扫描包时要包含的类-->
     <!-- <context:component-scan base-package="com.atguigu.spring.*" use-default-filters="false">
          type="annotation" : 表示哪种类型注解应用的Bean需要被扫描
          type="assignable" : 采用Bean的类型进行过滤
          <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
          <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
     </context:component-scan> -->

     <!--使用context:exclude-filter指定扫描包时不包含的类
      <context:component-scan base-package="com.atguigu.spring.*">
          <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
          <context:exclude-filter type="assignable" expression="com.atguigu.spring.component.UserService"/>
      </context:component-scan>
       -->

</beans>
7 自动装配注解@Autowired与@Resource
(1)  @Autowired
     ① 首先,根据byType进行装配,如果查找到一个,直接装配;
     ② 如果查找到多个相同类型的Bean对象,会再根据byName进行查找。
如果多个Bean对象中有Bean的id与属性名称相同,就直接装配
如果多个Bean对象中没有与Bean的属性名称相同的id,那么,报错。
    ③ 如果希望通过指定的名称id来装配Bean对象,可以借助于@Qualifier注解
    ④ 当查找不到Bean对象,装配不成功,会报错时,希望装配不到Bean对象就不再装配Bean对象了。可以设置@Autowired(required=false)
(2) @Resource
     @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
  @Resource装配顺序
   如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
   如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
   如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
   如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员学习圈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值