SpringIOC基础注解

2023-12-25 09:17 李志远 444

目标
  • Spring注解
  • Spring基于IOC的注解 - 基础注解
  • Spring IoC应用 - 整合MyBatis [XML配置]
  • Spring新注解 - 实现配置类[.java 文件实现XML配置]

1.Spring注解

1-1 Spring基于IOC的注解

  • Spring注解产生的背景
  • 传统XML配置会带来配置量过大,文件过多,不便于维护
  • 降低开发的效率
  • 注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合,只是配置的形式不一样
SpringBoot最终的选择是应用的基本配置(数据源,mybatis,事务等)用XML,业务Bean配置(@Service,@Controller…)用注解

a.注解配置IOC步骤:

步骤1: 在applicatioContext.xml spring核心配置文件中添加名字空间context,同时开启包扫描功能

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

        <!--base-package表示指定扫描的基础包,及子包是否存注解 可以使用逗号分隔多个包-->
        <context:component-scan base-package="com.woniu" />
</beans>

步骤2:在业务实现类及持久层类上添加注解

@Component("userService")
public class UserServiceImpl implements UserService {
}


@Component("userDao")
public class UserDaoImpl implements UserDao {
}

步骤3:从容器中获取对象

public class UserServiceTest {
    @Test
    public void testSave(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取Bean
        UserService userService = (UserService)ac.getBean("userService");
        UserDao userDao = (UserDao)ac.getBean("userDao");
        System.out.println(userService);
        System.out.println(userDao);
    }
}

b.关于Component注解

@Component("userService")
public class UserServiceImpl implements UserService {
}

相当于xml配置:

<bean id="userService" class="xx.xx.xx.UserSesrviceImpl">
    <property name="userDao" ref="userDao" />
</bean>

c.注入属性注解@Resource和 @Autowired

方式一: @Resource注解  [jdk中的注解]

@Resource(name="xxx")
private UserDao userDao;

@Resource小结:

1>   @Resource如果指定name,则按指定名称去容器中查询bean对象进行注入给属性

  2>  如果不指定name属性值,则默认按类型进行注入

  3>  如果该类型Bean对象找到多个,而不使用name指定,则报错

方式二: @Autowired 自动装配注解  - [spring提供]

@Autowired小结

1> @Autowired **默认按照类型查找Bean**,如果找到多个,则按属性名进行匹配,如果匹配不成功,则报错

 2> @Autowired ,如果匹配不成功,报错了,还可以使用注解@Qualifer("")指定注入bean名称

 3> 如果找不到对应bean对象,则会报错,此时指定@Autowired(required=false),则可以忽略错误 使用null

两种方式的注解添加到属性上之后,都不需需写setter,使用注解简化了代码

另外:这两个注解还可以定义在setter方法上

    @Autowired
    @Qualifier("userDaoImpl")
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
  • @Autowired和@Resource两个注解的区别:

(1)、@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配

(2)、@Autowired是Spring的注解,@Resource是J2EE的注解

d.其他基础注解

(1) 语义注解

针对三层架构代码定义语义注解: 实现效果都等价于@Component

    @Controller   --用于表示层

    @Service    --业务层

    @Respository --持久层

(2) @Value用于注入基本数据类型的值

@Value("张三")
private String name;
@Value("20")
private String age;

还可以使用@Value注入Properties文件中的属性

 <!--加载db.properties文件-->
 <context:property-placeholder location="classpath:db.properties" />

@Value("{{jdbc.username}")
private String name;
@Value("{{jdbc.driverClass}")
private String age;

(3) 关于作用域 生命周期

@Scope
@PostConstruct 初始化方法
@PreDestory 销毁

2.Spring IoC应用  - 整合MyBatis [XML配置]

  • Spring 整合MyBatis 实质就是要将MyBatis相关的配置纳入到Spring配置中为,MyBatis API对象【sqlSessionFactoiry,SqlSession,持久层接口代理子类对象】由Spring容器来创建并管理
  • 实现整合案例环境:
创建项目
添加依赖:
   mybatis
   mysql-jdbc
   logback
   Spring-context
   spring-mybatis 整合包  
   数据源依赖 - druid 
   [spring-jdbc.jar]    
       
配置文件: mybatis-config.xml
          logback.xml
           db.properties
       
smbms.t_user       

Spring-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.woniu" />

    <!--加载db.properties属性文件 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--数据源配置-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="{{jdbc.driverClass}"/>
        <property name="url" value="{{jdbc.url}"/>
        <property name="username" value="{{jdbc.username}"/>
        <property name="password" value="{{jdbc.password}"/>
        <!--关于连接池相关配置-->
        <property name="initialSize" value="{{druid.initalSize}"/>
        <property name="maxActive" value="{{druid.maxActive}" />
        <property name="minIdle" value="{{druid.minIdel}" />
    </bean>

    <!--使用mybatis.spring整合包中的会话工厂对象-->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入dataSource属性-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置xml映射文件中类型别名包-->
        <property name="typeAliasesPackage" value="com.woniu.entity" />
        <!--配置sqlXML映射文件的位置-->
        <property name="mapperLocations" value="com/woniu/mapper/*.xml" />
        <!--引用mybatis-config.xml配置-->
        <!--<property name="configLocation" value="classpath:mybatis-config.xml" />-->
    </bean>

    <!--指定持久层包,扫描包中所有Dao接口,创建代理子类对象-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指定sqlSessionFactoryBean的名称-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
        <!--
             指定Dao包,将针对此包中所有的dao接口造代理子类对象,并存入spring容器中
             相当于sqlSession.getMapper(UserDao.class)
         -->
        <property name="basePackage" value="com.woniu.dao"/>
    </bean>
</beans>

UserDao

package com.woniu.dao;

import com.woniu.entity.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserDao {
    //@Select("select * from t_user")
    public List<User> findUserList();
}

UserService及实现类

package com.woniu.service;

import com.woniu.entity.User;

import java.util.List;

public interface UserService {
    public List<User> findUserList();
}
-----------------------------------------------------------------------------------
package com.woniu.service.impl;

import com.woniu.dao.UserDao;
import com.woniu.entity.User;
import com.woniu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    /**
     * 查询用户列表
     * @return
     */
    public List<User> findUserList() {
        return userDao.findUserList();
    }
}

测试访问输出

import com.woniu.entity.User;
import com.woniu.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 * 模拟表示层
 */
public class UserServiceTest {
    @Test
    public void testFindUserList(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService = (UserService)ac.getBean("userService");
        List<User> userList = userService.findUserList();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

3 Spring新注解

  • spring提供的新注解主要是用于实现Java配置类
  • @Configuration 配置
  • 注解标注类上,表示此类为一个配置类
  • 在使用new AnnotationConfigurationApplicationContext(**配置类.class**)创建工厂ApplicatontContex
  • t当创建容器时会从该类上加载注解
  • @ComponentScan -- 作用:用于指定 spring 在初始化容器时要扫描的包
  • value和basePackages是相同的 String[]
@Configuration
@ComponentScan(basePackages = {"com.woniu.dao","com.woniu.service"})
public class SpringConfig {
}
  • @Bean - 只能标注在方法上,表示该方法用于创建Bean对象,存入Spring容器中,名称如果不指定为方法名
  • 将整合Mybatis配置的applicationContext.xml使用配置类实现:
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import javax.sql.DataSource;
import java.io.IOException;

@Configuration
@ComponentScan(basePackages = {"com.woniu.dao","com.woniu.service"})
public class SpringConfig {
    @Bean("dataSource")
    public DataSource getDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/smbms?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setInitialSize(4);
        dataSource.setMaxActive(20);
        dataSource.setMinIdle(20);
        return dataSource;
    }

    //此时方法需要指定参数dataSource,当容器调用@Bean注解方法时,会自动根据参数名查找容器,将对象通过参数传入
    @Bean("sqlSessionFactoryBean")
    public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = null;
        try {
            sqlSessionFactoryBean = new SqlSessionFactoryBean();
            //为 会话工厂Bean设置数据源对象
            sqlSessionFactoryBean.setDataSource(dataSource);
            sqlSessionFactoryBean.setTypeAliasesPackage("com.woniu.entity");

            ResourcePatternResolver loader = new PathMatchingResourcePatternResolver();
            //设置sql映射文件的位置
            sqlSessionFactoryBean.setMapperLocations(loader.getResources("classpath:com/woniu/mapper/*.xml"));
            // sqlSessionFactoryBean.setConfigLocation(loader.getResource("classpath:mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSessionFactoryBean;
    }

    @Bean
    public MapperScannerConfigurer getMapperScannerConfigurer(){
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
        configurer.setBasePackage("com.woniu.dao");
        return configurer;
    }
}
  • 测试
import com.woniu.config.SpringConfig;
import com.woniu.entity.User;
import com.woniu.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 * 模拟表示层
 */
public class UserServiceTest {
    @Test
    public void testFindUserList(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);

        UserService userService = (UserService)ac.getBean("userService");
        List<User> userList = userService.findUserList();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}