spring轻代码重配置,就导致了配置繁重,影响开发的效率,注解开发代替xml的配置文件,可以简化配置。spring原始注解主要是代替 < Bean>标签的配置。
主要分为基于xml的自动装配和基于注解的自动装配
基于xml的自动装配需要为每一个类需要自动装配的类中设置对应的set方法,否则会装配失败。
UserController
public class UserController {
//自动装配userService
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
public void saveUser(){
userService.saveUser();
}
}
UserService
public interface UserService {
void saveUser();
}
UserService实现类UserServiceImpl
public class UserServiceImpl implements UserService {
//自动装配userDao
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void saveUser() {
userDao.saveUser();
}
}
UserDao
public interface UserDao {
void saveUser();
}
UserDao实现类UserDaoImpl
public class UserDaoImpl implements UserDao {
@Override
public void saveUser() {
System.out.println("保存成功");
}
}
spring-autowire.xml
<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.xsd">
<bean id="userController" class="com.lx.controller.UserController" autowire="byType">
bean>
<bean id="userService" class="com.lx.service.impl.UserServiceImpl" autowire="byName">
bean>
<bean id="userDao" class="com.lx.dao.impl.UserDaoImpl">bean>
beans>
没有学自动装配之前是通过set注入的形式对属性进行赋值,自动装配只需要设置autowire属性即可。
测试类
public class AutoWireByXmlTest {
/*
* 自动装配:
根据指定的策略,在I0C 容器中匹配某个bean,自动为bean中的类类型的属性或接口类型的属性赋值
可以通过bean标签中的autowire属性设置自动装配的策略
自动装配的策略:
no,default: 表示不装配,即bean 中的属性不会自动匹配某个bean为属性赋值,此时属性使用默认值
byType:根据要赋值的属性的类型,在I0C 容器中匹配某个bean,为属性赋值
注意:
a>若通过类型没有找到任何一个类型匹配的bean,此时不装配,属性使用默认值
b>若通过类型找到了多个类型匹配的bean,此时会抛出异常: NoUniqueBeanDefinitionException
总结:当使用byType 实现自动装配时,IOC容器中有且只有一个类型匹配的bean 能够为属性赋值
* 3,byName: 将要赋值的属性的属性名作为bean的id在IOC容器中匹配某个bean,为属性赋值
*总结:当类型匹配bean有多个时, 此时可以使用byName实现自动装配
* */
@Test
public void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-autowire.xml");
UserController userController = context.getBean(UserController.class);
userController.saveUser();
}
}
基于注解的自动装配不需要设置set方法
<context:component-scan base-package="org.lx">
context:component-scan>
beans>
@Component,@Controller,@Service ,@Repository
上述4个注解都是加到类上的。
他们都可以起到类似bean标签的作用。可以把加了该注解类的对象放入Spring容器中。
实际再使用时选择任意一个都可以。但是后3个注解是语义化注解。
如果是Service类要求使用@Service。
如果是Dao类要求使用@Repository
如果是Controllerl类(SpringMVC中会学习到)要求使用@Controller
如果是其他类可以使用@Component
- @Component:将类标识为普通组件
- @Controller:将类标识为控制层组件
- @Service:将类标识为业务层组件
- @Repository:将类标识为持久层组倒.
通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名的首字母为小写的结果
可以通过标识组件的注解的value属性值设置bean的自定义的id
UserController
@Controller("userController")
public class UserController {
@Autowired
private UserService userService;
public void saveUser(){
userService.saveUser();
}
}
UserService
public interface UserService {
void saveUser();
}
UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public void saveUser() {
userDao.saveUser();
}
}
UserDao
public interface UserDao {
void saveUser();
}
UserDaoImpl
@Repository
public class UserDaoImpl implements UserDao {
@Override
public void saveUser() {
System.out.println("保存成功");
}
}
public class IOCByAnnotationTest {
@Test
public void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController controller = context.getBean("userController",UserController.class);
controller.saveUser();
}
}
如果一个bean已经放入Spring容器中了。那么我们可以使用下列注解实现属性注入,让Spring容器帮我们完成属性的赋值。
@Autowired
实现自动装配功能的注解,
加在要注入的成员变量上
@Service("userService")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public void show() {
userDao.show();
}
}
@Value
主要用于String,Integer等可以直接赋值的属性注入。不依赖setter方法,支持SpEL表达式。
@Service("userService")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Value("199")
private int num;
@Value("lx")
private String str;
@Value("#{19+3}")
private Integer age;
public void show() {
userDao.show();
}
}
@Qualifier
如果相同类型的bean在容器中有多个时,单独使用@AutoWired就不能满足要求,这时候可以再加上@Qualifier来指定bean的名字从容器中获取bean注入。
@Autowired
@Qualifier("userDao2")
private UserDao userDao;
@Resource
相当于@Autowired+ @Qualifier,按照名称进行注入,
加在要注入的成员变量上
@Resource("userDao2")
private UserDao userDao;
标注在类上,表示当前类是一个配置类。我们可以用注解类来完全替换掉xml配置文件。
注意:如果使用配置类替换了xml配置,spring容器要使用:AnnotationConfigApplicationContext
例如:
@Configuration
public class ApplicationConfig {
}
可以用来代替context:component-scan标签来配置组件扫描。
basePackages属性来指定要扫描的包。
注意要加在配置类上。
@Configuration
@ComponentScan(basePackages = "com.lx")//指定要扫描的包
public class ApplicationConfig {
}
可以用来代替bean标签,主要用于第三方类的注入。
使用:定义一个方法,在方法中创建对应的对象并且作为返回值返回。然后在方法上加上@Bean注解,注解的value属性来设置bean的名称。
例如:
@Configuration
@ComponentScan(basePackages = "com.lx")
public class ApplicationConfig {
@Bean("dataSource")
public DruidDataSource getDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource.setUsername("root");
druidDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_db");
druidDataSource.setPassword("root");
return druidDataSource;
}
}
注意事项:如果同一种类型的对象在容器中只有一个,我们可以不设置bean的名称
获取方式如下:
public static void main(String[] args) {
//创建注解容器
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ApplicationConfig.class);
//根据对应类的字节码对象获取
DataSource bean = app.getBean(DataSource.class);
System.out.println(userService);
}
可以用来代替context:property-placeholder,让Spring读取指定的properties文件。然后可以使用@Value来获取读取到的值。
使用:在配置类上加@PropertySource注解,注解的value属性来设置properties文件的路径。
然后在配置类中定义成员变量。在成员变量上使用@Value注解来获取读到的值并给对应的成员变量赋值。
properties配置文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_db
jdbc.username=root
jdbc.password=root
读取文件并且获取值
@Configuration
@ComponentScan(basePackages = "com.lx")
@PropertySource("jdbc.properties")
public class ApplicationConfig {
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DruidDataSource getDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUsername(username);
druidDataSource.setUrl(url);
druidDataSource.setPassword(password);
return druidDataSource;
}
}
注意事项:使用@Value获取读到的properties文件中的值时使用的是${key},而不是#{key}。