SSM—Spring(配置文件&注解总结)


1.Spring简介

Spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)AOP(Aspect Oriented Programming:面向切面编程) 为内核。

Spring的优势:

  • 方便解耦,简化开发,通过IOC容器可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度耦合
  • 支持AOP,可通过它实现传统OOP不容易实现的功能
  • 提供了众多企业级应用技术
    • SpringMVC(展现层)
    • Spring JDBCTemplate(持久层)
    • 事务管理(业务层)
  • 方便程序的测试
  • 方便集成各种优秀的框架
  • 降低JavaEE API的使用难度,Spring对其进行了封装

Spring体系结构
在这里插入图片描述

2.第一个Spring程序及其相关API

2.1 第一个Spring程序

1.导入spring坐标

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.12.RELEASE</version>
</dependency>

创建一个Dao接口和实现类

//UserDao
public interface UserDao {
    public void save();
}
//UserDaoImpl
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("UserDao is Running");
    }
}

2.创建配置文件

<?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-3.0.xsd">
	<!--    配置UserDaoImpl-->
    <bean id="userDao" class="com.kk.dao.impl.UserDaoImpl"/>
</beans>

3.测试

@Test
 public void test(){
 	//这些类的具体含义下面会总结
     ApplicationContext applicationContext = new
             ClassPathXmlApplicationContext("applicationContext.xml");
     UserDao userDao = (UserDao) applicationContext.getBean("userDao");
     userDao.save();
 }

测试结果
在这里插入图片描述

2.2 Spring相关API

Spring源码导读

  • ApplicationContext:是一个接口,代表应用上下文,可通过其实例获得Beans容器中的Bean对象。它有三个实现类:
    在这里插入图片描述
    • ClassPathXmlApplicationContext:从类的根路径下加载配置文件
    • FileSystemXmlApplicationContext:从磁盘路径上加载配置文件
    • AnnotationConfigApplicationContext:当使用注解配置容器对象时,需要使用此类来创建spring容器。它用来读取注解。
  • applicationContext.getBean(name / Class< T>):当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转;当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错。

3.配置文件详解_< bean/>

在配置文件中引入其他配置文件 : <import resource="xxx.xml/>"

3.1 bean标签

  • < bean id=" ",class=" ",{scope=" ", init_method=" ",destroy_method=" ",factory-bean=" ",factory-method=" "}>
  • 将配置对象交由Spring创建,默认调用类中的无参构造,若没有无参构造则创建失败
  • id=" ":Bean实例在Spring容器中的唯一标识,不能重复
  • class=" ":Bean的全限定性名称
  • scope=" ":指定对象的作用范围,取值如下:
    • singleton默认值,单例。加载配置文件时就会创建唯一一个实例;与容器共同创建、存活、销毁。
    • prototype:多例。调用getBeam()方法时才会创建对象,因此可以创建多个实例;对象只要使用就一直存活、长时间不用会被GC回收
    • 应用于WEB项目中 — request / session:Spring创建一个Bean对象,并将对象存入request / session域中;global session:应用在Portlet环境中(没有此环境则相当于session)
//测试scope:单例和多例
//首先,不更改配置文件,会发现两个对象地址一样,即为同一个对象;
//更改配置文件为:<bean id="userDao" class="com.kk.dao.impl.UserDaoImpl" scope="prototype"/>, 会发现两个对象的地址不一样
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
UserDao userDao1 = (UserDao) applicationContext.getBean("userDao");
System.out.println(userDao);
System.out.println(userDao1); 
  • 生命周期配置: init_method=" " 和 destroy_method=" " ,指定类中初始化方法销毁方法的名称

在实现类中编写初始化和销毁方法

public class UserDaoImpl implements UserDao {
  public UserDaoImpl(){
      System.out.println("无参构造");
  }
  public void init() {
      System.out.println("初始化");
  }
  public void destroy() {
      System.out.println("销毁");
  }
  public void save() {
      System.out.println("UserDao is Running");
  }
}

在配置文件中指定名称

<bean id="userDao" class="com.kk.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"/>
<!--多例-->
<!-- <bean id="userDao" class="com.kk.dao.impl.UserDaoImpl" scope="prototype" init-method="init" destroy-method="destroy"/> -->

测试

 @Test
 public void test(){
	  ApplicationContext applicationContext = new
	          ClassPathXmlApplicationContext("applicationContext.xml");
	  UserDao userDao = (UserDao) applicationContext.getBean("userDao");
	  userDao.save();
	  ((ClassPathXmlApplicationContext)applicationContext).close();
}

单例测试结果:与容器共同创建、存活、销毁
在这里插入图片描述
多例测试结果:对象只要使用就一直存活、长时间不用会被GC回收
在这里插入图片描述

  • Bean实例化的三种方式:
    • 无参构造实例化(默认方式):< bean id="userDao" class="com.kk.dao.impl.UserDaoImpl">
    • 工厂静态方法实例化:<bean id="userDao" class="com.kk.dao.factory.StaticFactory" factory-method="getUserDao"/>
    • 工厂实例方法实例化:
<bean id="factory" class="com.kk.dao.factory.DynamicFactory"/>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"/>

3.2 依赖注入

依赖注入(Dependency Injection): 是Spring框架核心IOC的具体实现。

通过控制反转,把对象的创建交给了Spring,即在进行业务层调用持久层方法时,Spring容器中会同时存在UserDao和UserService两个对象,而在业务层直接使用的只有UserService(没必要手动调用getBean()获得持久层实例),因此可以将UserDao实例注入到UserService实例中,只需要调用getBean()得到UserService实例即可。IOC解耦可以降低业务层和持久层之间的依赖关系。

注入的数据有三种类型:普通数据类型;引用;集合

3.2.1 引用注入

方式一:通过 set方法 和 P命名空间 注入

下面演示一个例子

业务层实现类

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    //通过set方法注入依赖
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void save() {
        //不注入依赖
//        ApplicationContext applicationContext = new
//                ClassPathXmlApplicationContext("applicationContext.xml");
//        UserDao userDao = (UserDao) applicationContext.getBean("userDao");
//        userDao.save();
        
        //通过set方法注入依赖
        userDao.save();
    }
}

配置文件

<bean id="userDao" class="com.kk.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.kk.service.impl.UserServiceImpl">
<!--这里的name="setUserDao()方法中set后面的userDao(将首字母改为小写),并不是类中的属性名,而ref中的参数等于上面的id="userDao"-->
    <property name="userDao" ref="userDao"/>
</bean>

<!--    使用p命名空间,需要在此文件上方引入xmlns:p="http://www.springframework.org/schema/p"-->
<!--    <bean id="userService" class="com.kk.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>-->

测试

@Test
public void test(){
   //测试依赖注入
		  //手动创建,此时会出现空指针,因为此实例并不是Spring容器创建的
//        UserService userService = new UserServiceImpl();
//        userService.save();
   //使用bean标签让Spring创建
   ApplicationContext applicationContext = new
           ClassPathXmlApplicationContext("applicationContext.xml");
   UserService userService = (UserService) applicationContext.getBean("userService");
   userService.save();
}

在这里插入图片描述
方式二:构造方法注入

业务层实现类

public UserServiceImpl() {
}
public UserServiceImpl(UserDao userDao) {
    this.userDao = userDao;
}

配置文件

 <bean id="userDao" class="com.kk.dao.impl.UserDaoImpl"/>
<!--    构造方法注入-->
 <bean id="userService" class="com.kk.service.impl.UserServiceImpl">
     <constructor-arg name="userDao" ref="userDao"/>
 </bean>

3.2.2 基本数据和集合注入

下面只使用set方法实现注入
在实现类中新增一些属性,并添加set方法和toString方法(这里不再粘贴)

public class UserDaoImpl implements UserDao {
    private String username;
    private List<String> strList;
    private Map<String, User> userMap;
    private Properties properties;
}

在配置文件中进行注入

<bean id="userDao" class="com.kk.dao.impl.UserDaoImpl">
    <property name="username" value="kk"/>
    <property name="strList">
        <list>
            <value>aaa</value>
            <value>bbb</value>
        </list>
    </property>
    <property name="userMap">
        <map>
            <!--ref代表引用-->
            <entry key="1" value-ref="user1"/>
            <entry key="2" value-ref="user2"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="1">p1</prop>
            <prop key="2">p2</prop>
        </props>
    </property>
</bean>
<!--    由于Map中的User为引用,所以仍需注入-->
<bean id="user1" class="com.kk.domain.User">
    <property name="id" value="1"/>
</bean>
<bean id="user2" class="com.kk.domain.User">
    <property name="id" value="2"/>
</bean>

测试结果
在这里插入图片描述

4.配置数据源

常见的数据源有(连接池):DBCP、CP30、BoneCP、Druid等。程序中会事先实例化数据源,初始化部分连接资源,要使用时从数据源中获取,使用完毕后将资源归还给数据源,以此来提高性能。下面来看看如何配置数据源:

1.导入数据源和数据库驱动的坐标

<!--数据源坐标-->
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.6</version>
</dependency>
<!--数据库驱动坐标坐标-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.24</version>
</dependency>

抽取数据库信息为.properties文件

jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=ture&characterEncoding=UTF-8&serverTimezone=UTC
jdbc.username = root
jdbc.password = root

在这里插入图片描述
利用Spring容器注入数据库信息

<?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-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
<!--    注意头部信息必须要引入context命名空间和约束路径-->
<!--    加载外部properties文件-->
    <context:property-placeholder location="classpath:db.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

测试

@Test
public void testC3P0() throws Exception {
    //利用spring容器和注入创建
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    ComboPooledDataSource dataSource = (ComboPooledDataSource) applicationContext.getBean("dataSource");
    Connection conn = dataSource.getConnection();
    System.out.println(conn);
}

5.Spring注解

使用注解代替xml配置文件可以简化配置,提高开发效率

5.1 原始注解

原始注解主要用来代替< bean/>配置

  • 用于在类上实例化Bean的注解:
    • @Component:使用在类上
    • @Controller:使用在web层
    • @Service:使用在service层
    • @Repository:使用在dao层
  • 用于注入的注解
    • @Autowired:使用在字段上,根据类型(从Spring容器中匹配Bean,若bean有多个则需要用下面的根据id的方式)进行依赖注入
    • @Qualifier: 结合@Autowired使用,根据名称(id)进行依赖注入
    • @Resource:相当于@Autowired+@Qualifier,根据名称(id)进行依赖注入
    • @Value:注入普通属性
  • @PostConstruct 和 @PreDestory,使用在方法上,标注该方法为Bean的初始化或销毁方法

首先,使用注解要先在配置文件中配置组件扫描,用来指定哪个包或子包下的Bean需要进行扫描

<!--    注意头部信息必须要引入context命名空间和约束路径-->
<!--    注解的组件扫描-->
<context:component-scan base-package="com.kk"/>

注解的使用
Dao层

//<bean id="userDao" class="com.UserDaoImpl">
//@Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {

    //@Value("1")
    @Value("${jdbc.driver}")
    private String driver;

    @Override
    public void save() {
        System.out.println(driver);
        System.out.println("save running");
    }
}

Service层

//@Component("userService")
@Repository("userService")
@Scope("singleton")
//@Scope("prototype")
public class UserServiceImpl implements UserService {

   //相当于<property name="userDao" ref="userDao"/>
   //使用注解进行依赖注入可以不用写set方法
   //@Autowired
   /*@Autowired
   @Qualifier("userDao")*/
   @Resource(name="userDao")
   private UserDao userDao;

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

5.2 新注解

  • @Configuration:指定当前类是一个Spring的核心配置类。创建容器时会从该类上加载注解
  • @ComponentScan:指定Spring在初始化容器时要扫描的包,等同于:< context:component-scan base-package=“com.kk”/>
  • @Bean:使用在方法上,标注将该方法的返回值存到容器中
  • @PropertySource:加载.properties文件中的配置
  • @Import:导入其他配置类

使用新注解完全代替核心配置文件
在这里插入图片描述

//加载配置文件
//<context:property-placeholder location="classpath:db.properties"/>
@PropertySource("classpath:db.properties")
public class DbSourceConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource")//会将该方法的返回值以此id(dataSource)存入到容器中
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}
//指定当前类是一个Spring的核心配置类
@Configuration
//    <!--    注解的组件扫描-->
//    <context:component-scan base-package="com.kk"/>
@ComponentScan("com.kk")
//<import resource=""/>
@Import({DbSourceConfig.class})
public class SpringConfig {

}

测试

    @Test
    public void test(){
        //注解代替配置文件,这里初始化使用AnnotationConfigApplicationContext类
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserDao userDao = (UserDao) applicationContext.getBean("userDao");
        userDao.save();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值