Spring实例化bean
一般获取bean对象会直接new出bean的实现类,或通过工厂类,但仍然需要自己通过new出factory实例化对象来调用getBean方法,或使用工厂的静态getBean方法调用;
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
//创建实例工厂对象
UserDaoFactory userDaoFactory = new UserDaoFactory();
//通过实例工厂对象的getUserDao方法创建UserDao对象
UserDao userDao = userDaoFactory.getUserDao();
userDao.save();
静态工厂就是将getUserDao方法使用static关键字修饰,通过类名.方法名调用,实现不用new出工厂对象来生成bean。
而借助spring这个第三方来管理Bean,用户不需要new出对象,而是直接使用IOC容器中存在的对象,可以做到解耦。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
Spring实例化bean的第四种方式是实现Spring提供的FactoryBean接口。相较于前两种通过工厂实例化bean的方法,此方法在Spring的xml配置上实现了简化。
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
public Class<?> getObjectType() {
return UserDao.class;
}
//是否为单例
public boolean isSingleton() {
return false;
}
}
Spring实例化bean的四种方式
Spring依赖注入
Spring依赖注入的三种方式
setter注入,通过set方法进行依赖注入。
构造器注入,通过有参构造器进行依赖注入。
自动注入,仍然需要set方法,通过bean标签的autowire属性进行依赖注入,一般使用byType进行类型自动注入(IOC容器中该类型必须唯一)。
(byName通过)
private int [] arr;
private List<String> list;
private Set<Integer> set;
private Map<Integer,String> map;
private Properties properties;
<bean id="userDao" class="com.wmxz.dao.Impl.UserDaoImpl">
<property name="arr">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
<property name="list">
<list>
<value>小明</value>
<value>小红</value>
<value>小华</value>
</list>
</property>
<property name="set">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
</set>
</property>
<property name="map">
<map>
<entry key="1" value="A"/>
<entry key="2" value="B"/>
<entry key="3" value="C"/>
</map>
</property>
<property name="properties">
<props>
<prop key="1">D</prop>
<prop key="2">E</prop>
<prop key="3">F</prop>
</props>
</property>
</bean>
引入其他配置文件(分模块开发)
Bean和依赖注入总结
创建容器的两种方式
- 类路径加载
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
- 绝对路径加载(不推荐)
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("D:\\applicationContext.xml");
获取bean的三种方式
Spring管理数据源对象
Maven中央仓库www.mvnrepository.com。
管理DruidDataSource对象。
- 导入druid坐标
- IOC容器中管理第三方bean:使用Ctrl+F12快捷键查看该类的成员结构,判断使用setter注入还是使用构造器注入。
- 获取IOC容器中管理的bean对象调用对象中的方法(这里我们没和我们的数据库连接,只做出了打印对象内存地址操作)。
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://loacalhost:3306/hadoop"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");
System.out.println(dataSource);
加载properties文件
加载properties文件:就是把刚才在bean对象当中做的依赖关系的value值,写入到properties文件当中,然后再获取value值
- 开启context命名空间。
- 使用context命名空间,加载指定properties文件。
- 使用${}读取加载的属性值。
jdbc.drive = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/hadoop
jdbc.username = root
jdbc.password = root
加载多个properties文件
加载多个properties文件时,在依赖注入时遇到相同key时,会让你自己选择。
原始注解开发
- 开启context命名空间。
- 使用@compenent对类进行注解。
@Component("userService")
//对于业务层,推荐使用@Service
public class UserServiceImpl implements UserService {}
@Component
//对于数据层,推荐使用@Repository
public class UserDaoImpl implements UserDao {}
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean(UserDaoImpl.class);
//userDao需要使用按类型才能获取到bean
UserService userService = (UserService) applicationContext.getBean("userService");
//UserService使用id获取bean
- 在spring的配置文件中使用context-scan对项目进行组件扫描。
<context:component-scan base-package="com.wmxz"/>
原始注解的规范使用
注解管理bean
使用注解@Scope管理bean的作用范围
@Repository
@Scope("singleton") //单例 默认
@Scope("prototype") //非单例
public class UserDaoImpl implements UserDao {}
使用注解管理bean的生命周期
@Repository
public class UserDaoImpl implements UserDao {
@PostConstruct //表明此方法为init方法
public void init(){
System.out.println("userDao的init");
}
@PreDestroy //表明此方法为destroy方法
public void destroy(){
System.out.println("userDao的destroy");
}
}
注意:destroy方法需要强制关闭容器或者使用关闭钩子才能够执行。同时,ApplictionContex接口中并不存在close方法与registerShutdownHook方法,所以需要使用它的实现类AnnotationConfigApplicationContext(FileSystemXmlApplicationContext与ClassPathXmlApplicationContext 同理)。
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
//使用ApplicationContext接口的实现类来关闭
applicationContext.close();//强制关闭容器
applicationContext.registerShutdownHook();//注册关闭钩子
注意:单例才会执行destroy方法,多例不会。
注解开发依赖注入
使用注解自动装配引用类型
@Resource(name = "userDao") //相当于@Autowired+@Qualifier("userDao")
使用注解依赖注入基本数据类型
//<bean id="userService" class="com.wmxz.service.impl.UserServiceImpl">
//@Component("userService")
@Service
//@Service("userService")
//@Scope("Singleton")
//@Scope("Prototpye")
public class UserServiceImpl implements UserService {
@Value("${jdbc.driver}")
private String driver;
//@Autowired //按类型自动装配
//@Qualifier("userDao") //按id自动装配
@Resource(name = "userDao") //相当于@Autowired+@Qualifier("userDao")
private UserDao userdao;
public void save() {
System.out.println("UserService的save方法,成员变量driver的值"+driver);
userdao.save();
}
@PostConstruct
public void init(){
System.out.println("UserService的init方法");
}
@PreDestroy
public void destroy(){
System.out.println("UserService的destroy方法");
}
}
新注解开发
Spring3.0升级了纯注解开发模式,使用Java类替代Spring核心配置文件,开启了Spring快速开发赛道。
@Configuration
@ComponentScan("com.wmxz")
public class SpringConfig {}
管理与注入第三方bean
管理第三方bean
注解注入第三方bean
加载properties文件
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/hadoop
jdbc.username = root
jdbc.password = root
@Value("${jdbc.username}") //获取properties文件的value
XML配置与注解配置对比
———————————————
Spring整合Junit
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:applicationContext.xml")
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
@Autowired
private UserService userService;
@Autowired
private DataSource dataSource;
@Test
public void test1() throws SQLException {
userService.save();
System.out.println(dataSource.getConnection());
}
}