目标
- 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);
}
}
}