第三次学习笔记总结了5点内容,分别是:bean之间的关系、 Spring 和 JSR 的 Annotaion 对比、Bean的初始化与销毁方法 三种配置方式、导入和混合配置、项目实战。
1. bean之间的关系
IOC容器中的Bean之前存在三种关系:
- 继承
- 依赖
- 引用
1.1继承
bean定义的继承: 不同于Java中的继承,这里指的是配置上的继承。在bean定义中包含了大量的配置信息,其中包括容器相关的信息(比如初始化方法、静态工厂方法名等等)以及构造器参数和属性值。子bean定义就是通过parent属性,从父bean定义继承配置数据的bean定义。它可以覆盖父bean的一些值,或者添加一些它需要的值。可以配置abstract属性为true使得这个Bean成为抽象Bean,抽象Bean不能被实例化,仅作为模板,用来被继承配置。
<bean id="abstractTeacher" class="com.pojo.Teacher" abstract="true">
<property name="cources" value="自动化"></property>
<property name="age" value="44"></property>
</bean>
<bean id="teacher1" parent="abstractTeacher">
<property name="name" value="张三"></property>
</bean>
<bean id="teacher2" parent="abstractTeacher">
<property name="name" value="李四"></property>
<property name="age" value="66"></property>
</bean>
1.2 依赖
Spring允许用户通过depends-on属性设定Bean前置依赖的Bean,前置依赖的Bean会在本Bean实例化之前创造好。如果有多个依赖的Bean则可以通过逗号或空格的方式配置Bean的名称。
<bean id="teacher" class="com.pojo.Teacher" depends-on="air">
<property name="name" value="诸葛亮"></property>
<property name="cources" value="自动化"></property>
<property name="age" value="44"></property>
</bean>
<bean id="air" class="com.pojo.Air">
<property name="name" value="空气"></property>
</bean>
如果没有depends-on所指定的对象,就会报错:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'teacher' defined in class path resource [ApplicationContext.xml]: 'teacher' depends on missing bean 'air'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'air' available
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:95)
at com.pojo.Test.main(Test.java:9)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'air' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:771)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:307)
... 7 more
1.3 引用
两个 Bean 之间通过 <ref> 建立依赖关系
<bean id="teacher" class="com.pojo.Teacher">
<property name="name" value="哈哈哈"></property>
<property name="age" value="44"></property>
</bean>
<bean id="stu" class="com.pojo.Student">
<property name="name" value="lisi44"></property>
<property name="age" value="99"></property>
<property name="tea" ref="teacher"></property>
</bean>
2. Spring 和 JSR 的 Annotaion 对比
Spring component model elements vs. JSR-330 variants
3 Bean的初始化与销毁方法 三种配置方式
3.1 使用xml配置
- 通过<bean> 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法
<bean id="stu" class="com.pojo.Student" init-method="init" destroy-method="destory">
3.2 使用注解
- 在指定方法上加上@PostConstruct或@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用
@PostConstruct
public void init() {
System.out.println("构造方法初始对象后调用。。。。");
}
@PreDestroy
public void destory() {
System.out.println("对象销毁前调用。。。");
}
3.3 显式配置
- 声明一个Java配置类,在配置类中使用@Bean注解声明一个组件
@Bean(initMethod="init",destroyMethod = "destory")
public Clazz createClazz() {
Clazz clazz=new Clazz();
clazz.setName("自动化专业");
return clazz;
}
4 导入和混合配置
在典型的 Spring 应用中,我们可能会同时使用自动和显式配置,在 spring 中这些配置方案都不是互斥的
- 在 JavaConfig 中引用 XML 配置
@Configuration
@import(AppConfig.class)
@importResource(“classpath:dao.xml”)
Public class AppConfig2{}
- 在 XML 中引用 JavaConfig
<beans>
<import resource=”dao.xml”/>
<bean id=”appconfig” class=”com.AppConfig”/>
</beans>
5.项目实战
项目完成了利用Spring容器,实现增加一条用户信息到数据库表中。
准备一张用户表
step1:导jar包
step2:ApplicationContext.xml文件的配置
- 因为项目采用的是annocation来初始化spring容器,故要进行annocation的配置
- 这里采用的Druid连接池,故要对连接池相关参数进行配置(百度)
- 后面的操作要使用QueryRunner来进行数据库的相关操作,故要初始化一个bean对象
下面就进入java代码的相关操作!!!!!!
step1:构建对应数据库表的javabean类 Admin
public class Admin {
private int id;
private String email;
private String upwd;
private String upur;
step2:定义dao层的接口及实现类,操作数据库
public interface AdminDao {
public void addAdmin(Admin admin);
}
@Repository
public class AdminDaoImp implements AdminDao {
@Autowired
QueryRunner run;
public void addAdmin(Admin admin) {
String sql="insert into admin(email,upwd,upur)values(?,?,?)";
try {
run.insert(sql,new BeanHandler<Admin>(Admin.class),admin.getEmail(),admin.getUpwd(),admin.getUpur());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
step3:定义service层的接口及实现类,操作dao层
public interface UserService {
public void addAdmin(Admin admin);
}
@Service
public class UserServiceImp implements UserService {
@Autowired
AdminDao admindao;
public void addAdmin(Admin admin) {
admindao.addAdmin(admin);
}
}
step4:定义control层,实现用户操作service层
@Controller
public class UserAction {
@Autowired
UserService us;
public void addAdmin(Admin admin)
{
us.addAdmin(admin);
}
}
step5:测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={"/ApplicationContext.xml"})
public class AppTest {
@Autowired
UserAction user;
@Test
public void addAdmin() {
Admin ad=new Admin("admin2@qq.com","123456","100100");
user.addAdmin(ad);
System.out.println("ok");
}
}
由此可以看出:spring实现了将各个类需要的对象,从spring容器中取出,自动注入的功能。
附:项目结构图: