IoC详解
1 Bean创建
- @Component,组件注解,用于将任意对象添加到spring容器中。
- @Controller,将web层的对象,添加到spring容器。
- @Service,将service层的对象,添加到spring容器。
- @Repository,将dao层的对象,添加到spring容器。
2 依赖注入
-
按照名称注入
public class 类名{ @Resource(name="名称") private 类型 变量; }
-
按照类型注入
public class 类名{ @Resource private 类型 变量; }
-
注册普通数据
@Value 可以给成员变量注入、也可以给属性注入(getter/setter)
-
properties数据注入
- 编写properties文件,key=value
- 加载 @PropertySource(“classpath:properties文件”)
- 注入数据 @Value("${key}")
package com.czxy.demo07_di_properties.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @PropertySource("classpath:demo07.properties") public class Demo07Configuration { @Value("${jdbc.driver}") private String driver; //给成员变量赋值 @Value("${jdbc.url}") public void setUrl(String url) { //给写属性赋值 System.out.println("url:" + url); System.out.println("driver:" + driver); } }
2.3 @Bean 注入第三方类
2.3.1 按照类型
-
模拟类
package com.czxy.demo08_bean_type.dao; public class UserDao { public void selectAll() { System.out.println("user dao "); } }
-
配置类
package com.czxy.demo08_bean_type.config; import com.czxy.demo08_bean_type.dao.UserDao; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Demo08Configuration { @Bean public UserDao createUserDao() { return new UserDao(); } }
-
测试类
package com.czxy.demo08_bean_type; import com.czxy.demo07_di_properties.config.Demo07Configuration; import com.czxy.demo08_bean_type.config.Demo08Configuration; import com.czxy.demo08_bean_type.dao.UserDao; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; @RunWith(SpringRunner.class) @ContextConfiguration(classes = Demo08Configuration.class) public class TestDemo08 { @Resource private UserDao userDao; @Test public void testDemo07() { // UserDao userDao = new UserDao(); userDao.selectAll(); } }
2.3.2 按照名称
-
模拟数据类
- 接口
- 实现类A
- 实现类B
-
配置类,创建2个实现类,并进行不同的命名
-
测试类,依次注入不同命名的实现类
-
实现
-
配置类
package com.czxy.demo09_bean_name.config; import com.czxy.demo09_bean_name.dao.UserDao; import com.czxy.demo09_bean_name.dao.impl.UserDaoImplA; import com.czxy.demo09_bean_name.dao.impl.UserDaoImplB; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Demo09Configuration { @Bean(name="userDaoA") public UserDao createUserDaoA() { return new UserDaoImplA(); } @Bean(name="userDaoB") public UserDao createUserDaoB() { return new UserDaoImplB(); } }
-
测试类
package com.czxy.demo09_bean_name; import com.czxy.demo09_bean_name.config.Demo09Configuration; import com.czxy.demo09_bean_name.dao.UserDao; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; /** * @author 桐叔 * @email liangtong@itcast.cn */ @RunWith(SpringRunner.class) @ContextConfiguration(classes = Demo09Configuration.class) public class TestDemo09 { @Resource(name="userDaoA") private UserDao userDaoA; @Resource(name="userDaoB") private UserDao userDaoB; @Test public void testDemo07() { userDaoA.selectAll(); userDaoB.selectAll(); } }
-
2.3.3 参数类型:引用数据
-
@Bean 修饰的方法,如果有参数,将自动注入。
-
步骤:
- 模拟类
- UserDao
- UserService
- 配置类
- 编写方法,createUserDao
- 编写方法,createUserService( UserDao userDao )
- 测试类
- 模拟类
-
实现
-
配置类
package com.czxy.demo10_bean_param.config; import com.czxy.demo10_bean_param.dao.UserDao; import com.czxy.demo10_bean_param.service.UserService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Demo10Configuration { @Bean public UserDao userDao() { return new UserDao(); } @Bean public UserService userService(UserDao userDao) { userDao.selectAll(); return new UserService(); } }
-
测试类
package com.czxy.demo10_bean_param; import com.czxy.demo09_bean_name.config.Demo09Configuration; import com.czxy.demo09_bean_name.dao.UserDao; import com.czxy.demo10_bean_param.config.Demo10Configuration; import com.czxy.demo10_bean_param.service.UserService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; @RunWith(SpringRunner.class) @ContextConfiguration(classes = Demo10Configuration.class) public class TestDemo10 { @Resource(name="userService") private UserService userService; @Test public void testDemo07() { userService.selectAll(); } }
-
2.3.4 参数类型:简单数据
-
properties配置文件
#key=value jdbc.driver=com.mysql.jdbc.cj.Driver jdbc.url=jdbc:mysql://localhost:3306/db2 user.username=jack user.password=6666
-
配置类
package com.czxy.demo11_bean_value.config; import com.czxy.demo10_bean_param.dao.UserDao; import com.czxy.demo10_bean_param.service.UserService; import com.czxy.demo11_bean_value.domain.User; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @PropertySource("classpath:demo07.properties") public class Demo11Configuration { @Bean public User createUser(@Value("${user.username}") String username, @Value("${user.password}") String password) { return new User(username,password); } }
-
测试类
package com.czxy.demo11_bean_value; import com.czxy.demo10_bean_param.service.UserService; import com.czxy.demo11_bean_value.config.Demo11Configuration; import com.czxy.demo11_bean_value.domain.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; @RunWith(SpringRunner.class) @ContextConfiguration(classes = Demo11Configuration.class) public class TestDemo11 { @Resource private User user; @Test public void testDemo07() { System.out.println(user); } }
2.4 Bean 作用域
- 默认2个作用域:
- 单例 singleton :整个spring容器只有一个。
- 多例 prototype:每获得一次创建一份。
2.4.1 单例
-
dao,确定作用域方式
package com.czxy.demo12_scope.dao; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; @Repository @Scope("singleton") public class UserDao { }
-
配置类
package com.czxy.demo12_scope.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = {"com.czxy.demo12_scope.dao"}) public class Demo12Configuration { }
-
测试类,注入2次,打印结果一样的。
package com.czxy.demo12_scope; import com.czxy.demo04_component.config.Demo04Configuration; import com.czxy.demo04_component.controller.StudentController; import com.czxy.demo12_scope.config.Demo12Configuration; import com.czxy.demo12_scope.dao.UserDao; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; @RunWith(SpringRunner.class) @ContextConfiguration(classes = Demo12Configuration.class) public class TestDemo12 { @Resource private UserDao userDao1; @Resource private UserDao userDao2; @Test public void testDemo4() { System.out.println(userDao1); System.out.println(userDao2); } }
2.4.2 多例
-
修改单例代码
package com.czxy.demo12_scope.dao; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; @Repository //@Scope("singleton") @Scope("prototype") public class UserDao { }
2.4.3 常量
package com.czxy.demo12_scope.dao;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
@Repository
//@Scope("singleton")
//@Scope("prototype")
//@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) //单例常量 singleton
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) //多例常量 prototype
public class UserDao {
}