Spring核心配置

spring实例化Bean的三种方式

  1. 使用类中的无参构造方法
    <bean id="people" class="com.young.action.People">
          <property name="id" value="1"></property>
          <property name="name" value="张三"></property>
    </bean>
  1. 使用静态工厂
    1. 创建工厂类
public class BeanFactory { 

     public static User getUser01() {
          return new User(1,"钢铁",18);
     }

     public static User getUser02() {
          return new User(2,"富贵",20);
     }
 }
2. class的值是工厂类的全路径,factory-method的值是需要调用的方法;工厂类中不同的方法创建了不同的实例,通过调用不同的方法获得不同的实例
<bean id="user1" class="com.young.factory.BeanFactory" factory-method="getUser01" ></bean>

测试

public class Test {

     public static void main(String[] args) {

          ApplicationContext app = new  ClassPathXmlApplicationContext("ApplicationContext.xml");

          User bean = (User) app.getBean("user1");
          System.out.println(bean);
     }
}
  1. 使用实例工厂
    1. 修改工厂类
      工厂类中的定义的是非静态方法,通过调用这些方法来获取石磊
public class BeanFactory { 

     public User getUser01() {
          return new User(1,"钢铁",18);
     }

     public User getUser02() {
          return new User(2,"富贵",20);
     }
 }
2. 更改xml
调用非静态方法就需要先创建实例,在调用方法
<bean id="beanFactory" class="com.young.factory.BeanFactory"></bean>
<bean id="user1" factory-bean="beanFactory" factory-method="getUser01" ></bean>
3. 测试
public class Test {
     public static void main(String[] args) {

          ApplicationContext app = new ClassPathXmlApplicationContext("ApplicationContext.xml");
          User bean = (User) app.getBean("user1");
          System.out.println(bean);
     }
}

Bean属性注入

1. 使用get set方法

Bean属性的注入是通过People的set方法给People实例的属性赋值的,因此property标签的name属性值people类中set方法的名字一样

    <bean id="people" class="com.young.action.People">
          <property name="id" value="1"></property>
          <property name="name" value="张三"></property>
    </bean>

2. 有参构造方法

type的值是对应属性的类型,可以省略,省略后,会自动识别属性的类型

  <bean id="people" class="com.young.action.People">
          <constructor-arg name="id" value="1" type="com.lang.Integer"></constructor-arg>
          <constructor-arg name="name" value="秋娴" type="com.lang.String"></constructor-arg>
</bean>

其他非常规属性的注入

数组

arr是一个String[]型的数组

<bean id="animal" class="com.young.action.Animal">
     <property name="arr">
          <array>
              <value>d1</value>
              <value>d2</value>
              <value>d3</value>
          </array>
     </property>
</bean>

arrBean是一个User[]型的数组

 <bean id="user" class="com.young.action.User">
     <property name="id" value="2"></property>
     <property name="name" value="富贵"></property>
     <property name="age" value="20"></property>
</bean>

<bean id="animal" class="com.young.action.Animal">
     <property name="arrBean">
          <array>
          <!-- 在内部定义一个实例 -->
              <bean class="com.young.action.User">
                   <property name="id" value="1"></property>
                   <property name="name" value="钢铁"></property>
                   <property name="age" value="18"></property>
              </bean>
              <!-- 引入外部的实例 -->
              <ref bean="user"/>
          </array>
     </property>
</bean>

map

params是一个Map<String,Object> 型的集合

<bean id="animal" class="com.young.action.Animal">
         <property name="params">
               <map>
                    <entry key="d1" value="秋娴"></entry>
                    <entry key="d2">
                          <bean class="com.young.action.People">
                              <property name="id" value="1"></property>
                              <property name="name" value="秋娴"></property>
                          </bean>
                    </entry>
               </map>
          </property>
</bean>

list

list是一个List型的集合,

<bean id="animal" class="com.young.action.Animal">
            <property name="list">
              <list>
                    <value>张三</value>
                    <value>李四</value>
                    <value>秋娴</value>
               </list>
          </property>
</bean>

listMap是一个List<Map<String,Object>>型的集合

<bean id="people" class="com.young.action.People">
          <constructor-arg name="id" value="1" type="com.lang.Integer"></constructor-arg>
          <constructor-arg name="name" value="钢铁" type="com.lang.String"></constructor-arg>
 </bean>


<bean id="animal" class="com.young.action.Animal">
<property name="listMap">
               <list>
                    <map>
                         <entry key="people01" value-ref="people"></entry>
                    </map>                
                    <map>
                         <entry key="d1" value="钢铁"></entry>
                         <entry key="d2">
                               <bean class="com.young.action.People">
                                  <property name="id" value="1"></property>
                                  <property name="name" value="钢铁"></property>
                              </bean>
                         </entry>
                    </map>
               </list>
          </property>
</bean>

listBean是一个List型的集合

<property name="listBean">
               <list>
                    <bean class="com.young.action.People">
                              <property name="id" value="1"></property>
                              <property name="name" value="秋娴"></property>
                    </bean>
                    <bean class="com.young.action.People">
                              <property name="id" value="2"></property>
                              <property name="name" value="张三"></property>
                    </bean>
                    <bean class="com.young.action.People">
                              <property name="id" value="2"></property>
                              <property name="name" value="李四"></property>
                    </bean>
               </list>
          </property>

Properties的注入

  1. Properties作为一个类的属性时
<bean id="xxx" class="xxxx">
     <property name="properties">
               <props>
                    <prop key="driver">com.mysql.jdbc</prop>
                    <prop key="url">jdbc:mysql://127.0.0.1:3306/</prop>
                    <prop key="userName">root</prop>
                    <prop key="password">ky123456</prop>
               </props>
          </property>
  1. 外部properties的引入
    外部properties的引入需要引入约束条件,并且引入properties文件;从properties中读取到的值可以用一个JavaBean接收
    在这里插入图片描述
<!--引入properties文件-->
    <context:property-placeholder location="classpath:JdbcUtil.properties"/>
       <bean id="dbProp" class="com.young.action.DbProp">
               <property name="driver" value="${driver}"></property>
               <property name="url" value="${url}"></property>
               <property name="userName" value="${username}"></property>
               <property name="password" value="${password}"></property>
       </bean> 

注意:以上的方式得到的userName的值为配置环境里的名称。
为了能获取properties中的值,有两种方法
第一种方法,将${userName}中的名称改成其它名称,名称不能为username,name,其它的都可以

   <context:property-placeholder location="classpath:JdbcUtil.properties"/>
       <bean id="dbProp" class="com.young.action.DbProp">
               <property name="driver" value="${driver}"></property>
               <property name="url" value="${url}"></property>
               <property name="userName" value="${name01}"></property>
               <property name="password" value="${password}"></property>
       </bean> 

第二种方法,在引入文件的标签中,加入 system-properties-mode,有两个参数值:
system-properties-mode
FALLBACK—>设置不去读取系统的环境变量 ,
ENVIRONMENT—>优先读取环境变量
将 system-properties-mode 设为FALLBACK;

   <context:property-placeholder location="classpath:JdbcUtil.properties" system-properties-mode="FALLBACK"/>
      <bean id="dbProp" class="com.young.action.DbProp">
              <property name="driver" value="${driver}"></property>
              <property name="url" value="${url}"></property>
              <property name="userName" value="${username}"></property>
              <property name="password" value="${password}"></property>
      </bean>

xml方式重构三层结构

写applicationContext.xml文件
ref的值是引用对象的id
在这里插入图片描述

public class UserDaoImpl implements UserDao {
     @Override
     public User query(int id) {
       User user = null;
          switch(id) {
              case 1:
                  user = new User(1,"张三",18);
                   break;
              case 2:
                  user = new User(2,"王富贵",19);
                   break;
              case 3:
                   user = new User(3,"钢铁",20);
                   break;
          }
          return user;
     }
}

UserServiceImpl.java

public class UserServiceImpl implements UserService {
     private UserDao userDao;
     public void setUserDao(UserDao userDao) {
          this.userDao = userDao;
     }
     
     @Override
     public User query(int id) {
          return new UserDaoImpl().query(id);
     }
}

Action.java

public class Action {
    UserService userService;
     
    public void setUserService(UserService userService) {
         this.userService = userService;
     }
     
    public void getUser() {
          int id = 1;
          User user = userService.query(id);
          System.out.println(user);
     }
}

测试

public class TestSpring {
     public static void main(String[] args) {
          ApplicationContext app = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
          Action bean = (Action) app.getBean("action");
          bean.getUser();
    }
}

在回过头来看applicationContext.xml文件,如果把bean标签内的property标签删除,再进行测试,就会报空指针异常

<!--以下配置会报空指针异常-->
<!--创建UserDao实例-->
<bean id="userDao" class="com.young.dao.Impl.UserDaoImpl">
</bean>
<!--ref指向UserDao实例-->
<bean id="userService"   class="com.young.service.impl.UserServiceImpl">
</bean>
<!--ref指向UserService实例-->
<bean id="action" class="com.young.action.Action">
</bean>

如何解决这类问题呢?
在Spring中,可以自动创建实例,通过给bean标签的属性autowire赋值,来设置如何创建实例,这就是自动装配,以下实现自动装配的配置

<bean id="userDao" 
class="com.young.dao.Impl.UserDaoImpl">
</bean>

<bean id="userService"   
          class="com.young.service.impl.UserServiceImpl" autowire="byName">
</bean>

<bean id="action" 
          class="com.young.action.Action"  autowire="byName">
</bean>

autowire有两个值

  1. byName–>根据对象里面的属性名取IOC容器里找对应id的对象
  2. byType–>根据对象里面属性的类型取Ioc容器里面找对象

在开发中,随着需求的增多,servlet类,Dao类,Service类会非常多,如果他们的配置都写在一个文件中的话,会特别的繁琐,为解决这个问题,于是就有了拆分配置文件这种骚操作

拆分配置文件

将applicationContext.xml 分成是三个文件

  1. application-dao.xml—>专门dao的bean标签
  2. application-service.xml—>专门放service的bean标签
  3. application-servlet.xml—>专门放action的bean标签
    然后在applicationContext.xml中导入各个xml文件,这个文件什么也不写,只写导入的标签
  4. 配置application-dao.xml文件
<bean id="userDao" 
class="com.young.dao.Impl.UserDaoImpl">
</bean>
  1. 配置application-service.xml文件
<bean id="userService"   
          class="com.young.service.impl.UserServiceImpl" autowire="byName">
</bean>
  1. 配置application-servlet.xml文件
<bean id="servlet" 
          class="com.young.servlet.UserServlet"  autowire="byName">
</bean>
  1. 在applicationContext.xml中导入各个xml文件
<import resource="application-servlet.xml"/>
<import resource="application-dao.xml"/>
<import resource="application-service.xml"/>

那么有没有更牛皮的方式呢?何谓更牛皮的方式,就是配置文件都不用写了,就可以进行操作了;这就是注解方式重构三层结构

注解方式重构三层结构

就是同过注解的方式,实现不用写配置 文件也能创建实例,有以下几个注解
@Component 代表一个spring的组件 ,加载在类上
@Controller 被Component 注解了。主要作用于接收用户请求的类
@Service 被Component 注解了 主要作用于服务层
@Repository 被Component 注解了 主要作用于数据访问层
@Autowired 作用于类里面的属性或方法 用于自动从IOC容器里面根据类型去装配,加载在类的属性或方法上
只使用@Component和@Autowired两个注解就可以实现创建实例的功能了,@Controller ,@Service,@Repository都加载了@Component
useDaoImpl.java

@Component
public class UserDaoImpl implements UserDao {
     @Override
     public User query(int id) {
          User user = null;
          switch(id) {
              case 1:
                  user = new User(1,"秋娴",18);
                   break;
              case 2:
                   user = new User(2,"王富贵",19);
                   break;
              case 3:
                   user = new User(3,"钢铁",20);
                  break;
          }
          return user;
     }
}

UserServiceImpl.java

@Component

public class UserServiceImpl implements UserService {
     @Autowired
     private UserDao <u>userDao</u>;
     @Override
     public User query(int id) {
          return new UserDaoImpl().query(id);
     }
}

UserServlet.java

@Component

public class UserServlet {
     @Autowired
     UserService userService;
     
     public void getUser() {
          int id = 1;
          User user = userService.query(id);
          System.out.println(user);
     }
}

在applicationContext.xml文件中写入扫描标签,标签的内容是需扫描的包,其作用是扫描各个类中的注解

<context:component-scan base-package="com.young.dao.Impl"></context:component-scan>
<context:component-scan base-package="com.young.service.impl"></context:component-scan>
<context:component-scan base-package="com.young.servlet"></context:component-scan>

测试

public class TestSpring {

     public static void main(String[] args) {

          ApplicationContext app = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

          UserServlet bean = (UserServlet) app.getBean(UserServlet.class);
          bean.getUser();
     }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值