spring IOC 注解开发 注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。
注解开发入门
创建Maven工程,添加依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> </dependencies>
|
使用@Component注解配置管理的资源
- eg: 需要给AccountServiceImpl
@Component("accountService") public class AccountServiceImpl implements AccountService {}
|
引入context的命名空间
- applicationContext.xml中需要引入context的命名空间,可在xsd-configuration.html中找到
<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"> </beans>
|
配置扫描
在beans标签内部,使用context:component-scan ,让spring扫描该基础包下的所有子包注解
<context:component-scan base-package="com.jwang"></context:component-scan>
|
注解开发进阶
用于创建对象的
相对于相当于: <bean id="" class="">
@Component
作用:
把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
属性:
value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。
@Controller @Service @Repository
web里面的三层结构中的所有类,在spring里面都称之为 Component (组件) , 但是它也提供了更详细的注解来针对不同的层级声明 。
三个衍生注解如下:
@Controller :修饰WEB层类 —>web | SpringMVC
@Service :修饰业务层类 —>service
@Repository :修饰DAO层类 —>dao
在需要spring创建对象的类上面使用注解 @Component(“us”) 即可.Spring看类上是否有该注解,如果有该注解,生成这个类的实例。如果不指定value值, 那么默认的id值就是类名的名字, 第一个字母小写.
用于改变作用范围的@Scope
@Scope
singleton: 单例(默认)
prototype:多例
@Scope注解用来描述类的作用范围的,默认值singleton。如同xml中bean标签的属性scope <bean scope=""/>.如果配置成多例的使用prototype。
@Scope("prototype") @Component("accountService") public class AccountServiceImpl implements AccountService {}
|
和生命周期相关的
初始化和销毁回调方法对应的注解
@PostConstrut:如同xml中bean标签的属性init-method <bean init-method=""/>,用来设置spring框架初始化此类实例时调用的初始化方法,标注在此类的初始化方法上
@PreDestroy:如同xml中bean标签的属性destroy-method <bean destroy-method=""/>,用来设置spring框架销毁此类实例时调用的销毁方法,标注在此类的销毁方法上
注意:这两个注解都是配在方法上的
使用注解注入属性
@Value
@Value("奥巴马") private String name;
|
@Autowired
作用:
自动按照类型注入。当使用注解注入属性时, set 方法可以省略。它只能注入其他 bean 类型。
如果只有一个实现类, 可以自动注入成功
如果有两个或者两个以上的实现类, 找到变量名一致的id对象给注入进去, 如果找不到,就报错
实例:
@Component("accountService") public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Override public void save() { System.out.println("AccountServiceImpl---save()"); accountDao.save(); } }
|
@Qualifier
package com.jwang.controller;
import com.jwang.service.UserService; import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller public class UserController { @Autowired @Qualifier("userServiceImplAnother") private UserService userService; public String getName(){ return userService.getName(); } }
|
@Resource
如果上面一个接口有多种实现,那么现在需要指定找具体的某一个实现,那么可以使用@Resource
package com.jwang.controller;
import com.jwang.service.UserService; import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller public class UserController { @Resource(name = "userServiceImpl") private UserService userService; public String getName(){ return userService.getName(); } }
|
混合开发
注解和XML比较

- xml
- 优点: 方便维护, 改xml文件
- 缺点: 相对注解而言, 麻烦一点
- 注解
- 优点: 开发简洁方便
- 缺点: 维护没有xml那么方便, 需要改源码
混合开发特点
IOC: 自己写的类使用注解进行IOC,非自己写的类使用配置文件进行IOC
DI: 如果一个类是使用注解进行IOC的,那么它的属性使用注解进行注入;如果一个类是使用配置文件进行IOC,那么它的属性使用配置文件进行注入
混合开发环境搭建
引入外部properties文件
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--1. 创建DataSource对象--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> <property name="url" value="${jdbc.url}"></property> <property name="driverClassName" value="${jdbc.driver}"></property> </bean>
|
使用mybatis和注解改造增删改查案例
package com.jwang.controller;
import com.jwang.pojo.Account; import com.jwang.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;
import java.sql.SQLException; import java.util.List;
@Controller public class AccountController { @Autowired private AccountService accountService;
public List<Account> findAll() throws SQLException { return accountService.findAll(); }
public Account findById(int id) throws SQLException { return accountService.findById(id); }
public void deleteById(int id) throws SQLException { accountService.deleteById(id); }
public void add(Account account) throws SQLException { accountService.add(account); }
public void update(Account account) throws SQLException { accountService.update(account); } }
|
package com.jwang.service.impl;
import com.jwang.dao.AccountDao; import com.jwang.pojo.Account; import com.jwang.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import java.sql.SQLException; import java.util.List;
@Service public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao;
@Override public List<Account> findAll() throws SQLException { return accountDao.findAll(); }
@Override public Account findById(int id) throws SQLException { return accountDao.findById(id); }
@Override public void deleteById(int id) throws SQLException { accountDao.deleteById(id); }
@Override public void add(Account account) throws SQLException { accountDao.add(account); }
@Override public void update(Account account) throws SQLException { accountDao.update(account); } }
|
package com.jwang.dao;
import com.jwang.pojo.Account;
import java.sql.SQLException; import java.util.List;
public interface AccountDao {
public List<Account> findAll() throws SQLException;
public Account findById(int id) throws SQLException;
public void deleteById(int id) throws SQLException;
public void add(Account account) throws SQLException;
public void update(Account account) throws SQLException; }
|
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.jwang.dao.AccountDao"> <insert id="add" parameterType="Account"> insert into account(name,money) values (#{name},#{money}) </insert> <update id="update" parameterType="Account"> update account set name=#{name},money=#{money} where id=#{id} </update> <delete id="deleteById" parameterType="int"> delete from account where id=#{id} </delete>
<select id="findAll" resultType="Account"> select * from account </select>
<select id="findById" resultType="Account" parameterType="int"> select * from account where id=#{id} </select> </mapper>
|
<?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"> <!--混合开发--> <!--1. 包扫描--> <context:component-scan base-package="com.jwang"/> <!-- 整合mybatis: 1. 配置DataSource 2. 配置SqlSessionFactoryBean 注入数据源 注入别名包扫描 3. 配置MapperScannerConfigurer,进行Dao接口的包扫描 注入要扫描的dao接口所在的包 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="username" value="root"></property> <property name="password" value="123"></property> <property name="url" value="jdbc:mysql:///day20?characterEncoding=utf8"></property> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="typeAliasesPackage" value="com.jwang.pojo"></property> </bean> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.jwang.dao"></property> </bean> </beans>
|
log4j.rootLogger=DEBUG,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %t %l %d %rms:%m%n log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=D:\\idea_project\\jwang_mm_backend.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS\} %-5p [%t] {%c}-%m%n
|
使用纯注解改造增删改查
基于注解的IoC配置已经完成,但是大家都发现了一个问题:我们依然离不开spring的xml配置文件,那么能不能不写这个applicationContext.xml,所有配置都用注解来实现呢?
纯注解开发原因:
- 方便大家学习SpringBoot
- 以防万一真遇到了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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--包扫描,扫描注解--> <context:component-scan base-package="com.jwang"/> <!--spring整合mybatis的配置文件--> <!-- 要进行ssm的整合,第一步:将sqlSessionFactory对象交给spring核心容器管理 sqlSessionFactoryBean对象,就是管理SQLSession创建Dao代理对象的 创建代理对象的目的是执行SQL语句
--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--将数据源注入进来--> <property name="dataSource" ref="dataSource"/> <!--注入核心配置文件的路径--> <property name="configLocation" value="classpath:SqlMapConfig.xml"/> </bean> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="root"/> <property name="password" value="123"/> <property name="url" value="jdbc:mysql:///day11?characterEncoding=utf-8"/> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> </bean> <!-- 第二步:一定要让spring核心容器去扫描dao接口,去加载dao接口的代理对象 --> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--指定要扫描的dao接口的包--> <property name="basePackage" value="com.jwang.dao"/> </bean> </beans>
|
实现
@Configuration
@Configuration public class SpringConfig {
}
|
@ComponentScan
@Configuration @ComponentScan(basePackages = "com.jwang") public class SpringConfig {
}
|
@Bean
@Configuration @ComponentScan(basePackages = "com.jwang") public class SpringConfig { @Bean public DataSource getDataSource(){ DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUsername("root"); dataSource.setPassword("123"); dataSource.setUrl("jdbc:mysql:///day20?characterEncoding=utf8"); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); return dataSource; }
@Bean public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource){ SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); sqlSessionFactoryBean.setTypeAliasesPackage("com.jwang.pojo"); return sqlSessionFactoryBean; }
@Bean public MapperScannerConfigurer getMapperScannerConfigurer(){ MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setBasePackage("com.jwang.dao"); return mapperScannerConfigurer; } }
|
通过注解获取容器
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
|