Spring2

Spring-02

4.22、IOC之组件创建顺序
实验20:bean之间的依赖 depends-on 属性

bean对象

public class A {
public A() {
System.out.println(“A 被创建了”);
}
}
public class B {
public B() {
System.out.println(“B 被创建了”);
}
}
public class C {
public C() {
System.out.println(“C 被创建了”);
}
}

applicationContext.xml配置:

<!-- 默认情况下。bean对象创建的顺序,是从上到下
		depends-on 可以设定依赖
 -->
<bean id="a" class="com.atguigu.pojo.A" depends-on="b,c"/>
<bean id="b" class="com.atguigu.pojo.B" />
<bean id="c" class="com.atguigu.pojo.C" />

测试代码:

@Test
public void test1() throws Exception {
	
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
}

4.24、基于xml配置文件的自动注入
先创建Person类和Car类
public class Car {
private String carNo;
private String name;

public class Person {

private Car car;

public Person(Car car) {
	this.car = car;
}

applicationContext.xml配置文件:

<bean id="car1" class="com.atguigu.pojo.Car">
	<property name="carNo" value="京B23412" />
	<property name="name" value="劳死来死"/>
</bean>
<bean id="car2" class="com.atguigu.pojo.Car">
	<property name="carNo" value="京B23412" />
	<property name="name" value="劳死来死2"/>
</bean>
<!-- 
	autowire 属性设置是否自动查找bean对象并给子对象赋值
	
	default 和 no 表示不自动查找并注入(你不赋值,它就null)
	byName 	是指通过属性名做为id来查找bean对象,并注入
				1、找到就注入
				2、找不到就为null
	byType  是指按属性的类型进行查找并注入
				1、找到一个就注入
				2、找到多个就报错
				3、没有找到就为null
	constructor 是指按构造器参数进行查找并注入。
				1、先按照构造器参数类型进行查找并注入
				2、如果按类型查找到多个,接着按参数名做为id继续查找并注入。
				3、按id查找不到,就不赋值。
 -->
<bean id="p19" class="com.atguigu.pojo.Person" autowire="constructor">
	<property name="name" value="p19" />
</bean>

测试代码:

@Test
public void test2() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	System.out.println(applicationContext.getBean("p19"));
}

4.23、IOC之Bean的单例和多例(重点)
实验21:测试bean的作用域,分别创建单实例和多实例的bean★

applicationContext.xml配置文件:

<!-- 
	scope 属性设置对象的域
		singleton			表示单例(默认)
							1、Spring容器在创建的时候,就会创建Bean对象
							2、每次调用getBean都返回spring容器中的唯一一个对象
							
		prototype			表示多例
							1、多例在Spring容器被创建的时候,不会跟着一起被创建。
							2、每次调用getBean都会创建一个新对象返回
							
		request				在一次请求中,多次调用getBean方法都是返回同一个实例。
		
							getBean("p20"); 底层大概的实现原理
								
							Object bean = request.getAttribute("p20");
							if (bean == null) {
								bean = new 对象();
								request.setAttribute("p20",bean);
							}
							return bean;
							
							
		session				在一个会话中,多次调用getBean方法都是返回同一个实例。
		
							getBean("p20"); 底层大概的实现原理
								
							Object bean = session.getAttribute("p20");
							if (bean == null) {
								bean = new 对象();
								session.setAttribute("p20",bean);
							}
							return bean;
 -->
<bean id="p20" class="com.atguigu.pojo.Person" scope="singleton">
	<property name="name" value="p20" />
</bean>

测试代码:

@Test
public void test3() throws Exception {
	
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	System.out.println( applicationContext.getBean("p20") );
	System.out.println( applicationContext.getBean("p20") );
	System.out.println( applicationContext.getBean("p20") );
	System.out.println( applicationContext.getBean("p20") );
	
}

5、对象的生命周期
5.1、IOC之Bean的生命周期
实验22:创建带有生命周期方法的bean

<!-- 
	init-method配置初始化方法(bean对象创建之后)
	destroy-method配置销毁方法(在spring容器关闭的时候,只对单例有效)
 -->
<bean id="p21" class="com.atguigu.pojo.Person" init-method="init" destroy-method="destroy" scope="singleton">
	<property name="name" value="p21"/>
</bean>

测试的代码:

@Test
public void test4() throws Exception {
	ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	applicationContext.getBean("p21");
	applicationContext.close();
}

5.2、Bean的后置处理器BeanPostProcessor
后置处理器,可以在bean对象的初始化方法前/后,做一些工作。

后置处理器使用步骤:
1、编写一个类去实现BeanPostProcessor接口
2、到Spring容器配置文件中配置

实验23:测试bean的后置处理器

代码:

public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 初始化方法之后调用
*/
@Override
public Object postProcessAfterInitialization(Object bean, String id) throws BeansException {
System.out.println(“初始化方法之后。正在初始化的对象bean->” + bean + “,正在初始化对象的id值->” + id);

	if ("p21".equals(id)) {
		Person person = (Person) bean;
		person.setName("这是我给的值");
	}
	
	return bean;
}

/**
 * 初始化方法之前调用
 */
@Override
public Object postProcessBeforeInitialization(Object bean, String id) throws BeansException {
	System.out.println("初始化方法之前。正在初始化的对象bean->" + bean + ",正在初始化对象的id值->" + id);
	return bean;
}

}

applicationContext.xml配置:

<bean id="p21" class="com.atguigu.pojo.Person" init-method="init" destroy-method="destroy" scope="singleton">
	<property name="name" value="p21"/>
</bean>
<!-- 配置自定义的后置处理器 -->
<bean class="com.atguigu.postprocessor.MyBeanPostProcessor" />

测试代码:

@Test
public void test4() throws Exception {
	ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	System.out.println( applicationContext.getBean("p21") );
	applicationContext.close();
}

6、Spring管理数据库连接池(重点)
6.1、Spring配置管理数据库连接池对象(重点)
创建一个Java工程。

导入jar包

commons-logging-1.1.3.jar
druid-1.1.9.jar
mysql-connector-java-5.1.37-bin.jar
spring-beans-4.3.18.RELEASE.jar
spring-context-4.3.18.RELEASE.jar
spring-core-4.3.18.RELEASE.jar
spring-expression-4.3.18.RELEASE.jar

applicationContext.xml配置:

<?xml version="1.0" encoding="UTF-8"?>

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
	<property name="username" value="root" />
	<property name="password" value="root" />
	<property name="driverClassName" value="com.mysql.jdbc.Driver" />
	<property name="url" value="jdbc:mysql://localhost:3306/test" />
	<property name="initialSize" value="5" />
	<property name="maxActive" value="10" />
</bean>

测试代码:

@Test
public void test1() throws Exception {
	
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	
	DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");
	
	System.out.println( dataSource.getConnection() );
	
}

6.2、Spring引入单独的jdbc.properties配置文件(重点)

创建jdbc.properties属性配置文件

username=root
password=root
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
initialSize=5
maxActive=10

applicationContext.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<!-- PropertyPlaceholderConfigurer类专门用来加载properties属性配置文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<!-- location属性设置你要加载的文件路径 
				classpath: 表示从类路径下搜索
	-->
	<property name="location" value="classpath:jdbc.properties" />
</bean>

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
	<property name="username" value="${username}" />
	<property name="password" value="${password}" />
	<property name="driverClassName" value="${driverClassName}" />
	<property name="url" value="${url}" />
	<property name="initialSize" value="${initialSize}" />
	<property name="maxActive" value="${maxActive}" />
</bean>

6.3、使用context名称空间加载jdbc.properties配置文件(重点)

添加context名称空间:

修改jdbc.properties属性配置文件:
user=root
password=root
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
initialSize=5
maxActive=10

applicationContext.xml配置文件:

<!-- 标签用来代替PropertyPlaceholderConfigurer加载属性配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
	<property name="username" value="${user}" />
	<property name="password" value="${password}" />
	<property name="driverClassName" value="${driverClassName}" />
	<property name="url" value="${url}" />
	<property name="initialSize" value="${initialSize}" />
	<property name="maxActive" value="${maxActive}" />
</bean>

7、Spring EL表达式(了解内容)
创建java实体Bean对象
public class Person {
private int id;
private String name;
private String phone;
private double salary;
private Car car;

public class Car {

private String name;
private String carNo;

实验26:[SpEL测试I]在SpEL中使用字面量

使用格式:#{数值} #{“字符串” || ‘字符串’}

实验27:[SpEL测试II]在SpEL中引用其他bean

使用格式:#{bean的id}

实验28:[SpEL测试III]在SpEL中引用其他bean的某个属性值

使用格式: #{bean.属性名}

实验29:[SpEL测试IV]在SpEL中调用非静态方法

使用格式: #{bean.方法名(参数)}

实验30:[SpEL测试V]在SpEL中调用静态方法

使用格式:#{T(全名类).方法名(参数)}

实验31:[SpEL测试VI]在SpEL中使用运算符

使用格式:#{表达式}

applicationContext.xml配置:

<bean id="car" class="com.atguigu.pojo.Car">
	<property name="carNo" value="京B123412" />
	<property name="name" value="蓝脖鸡泥" />
</bean>
<bean id="person" class="com.atguigu.pojo.Person">
	<property name="id" value="#{100}" />
	<property name="car" value="#{car}"></property>
	<property name="name" value="#{T(com.atguigu.pojo.Car).staticFun()}"></property>
	<property name="salary" value="#{10000 * 10}" />
</bean>

8、注解功能(极其重要)
8.1、注解配置Dao、Service、Controller组件
实验32:通过注解分别创建Dao、Service、Controller★
Spring配置bean的常用注解有
@Controller 配置控制器
@Service service业务层组件
@Repository 持久层dao组件
@Component 除了以上三种都可以用component
@Scope 配置作用域(单例,多例)

bean对象
/**

  • @Component 注解表示

*/
@Component
public class Book {
}

/**

  • @Repository 注解表示

  • @Repository(“abc”) 表示


  • /
    @Repository
    @Scope(“prototype”)
    public class BookDao {
    }
    /
    *
  • @Service 注解表示

/
@Service
public class BookService {
}
/
*

  • @Controller 注解表示

*/
@Controller
public class BookController {
}

applicationContext.xml配置文件;

<!-- 配置包扫描
		base-package	设置需要扫描的包名(它的子包也会被扫描)
 -->
<context:component-scan base-package="com.atguigu"></context:component-scan>

测试代码:

@Test
public void test1() throws Exception {

	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

	System.out.println(applicationContext.getBean("bookDao"));
	System.out.println(applicationContext.getBean("bookDao"));
	System.out.println(applicationContext.getBean("bookDao"));
	System.out.println(applicationContext.getBean("book"));
	System.out.println(applicationContext.getBean("bookService"));
	System.out.println(applicationContext.getBean("bookController"));

}

8.2、指定扫描包时的过滤内容
实验33:使用context:include-filter指定扫描包时要包含的类
实验34:使用context:exclude-filter指定扫描包时不包含的类

<context:include-filter />	设置包含的内容

注意:通常需要与use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。即:通过将use-default-filters属性设置为false,
<context:exclude-filter /> 设置排除的内容
在这里插入图片描述

applicationContext.xml 中配置的内容如下

<!-- use-default-filters="false" 设置取消默认包含规则 -->
<context:component-scan base-package="com.atguigu" use-default-filters="false">
	<!-- context:include-filter 设置包含的内容 -->
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
	<!-- context:exclude-filter 设置排除的内容 -->
	<context:exclude-filter type="assignable" expression="com.atguigu.service.BookService"/>
</context:component-scan>

以上配置会包含所有@Service注解的类。排除com.atguigu.service.BookService类

<!-- 配置包扫描
		base-package	设置需要扫描的包名(它的子包也会被扫描)
		use-default-filters="false" 去掉包扫描时默认包含规则
 -->
<context:component-scan base-package="com.atguigu" use-default-filters="false">
	<!-- 指定排除的内容
			type="annotation" 按注解进行过滤
			expression 注解的表达式(什么注解或注解的全类名)
	<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
	<context:exclude-filter type="assignable" expression="com.atguigu.controller.BookController"/> -->
	 <!-- 
	 		type="annotation" 按注解进行过滤
	  -->
	 <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
	 <context:include-filter type="assignable" expression="com.atguigu.controller.BookController"/>
</context:component-scan>

8.3、使用注解@Autowired自动装配
实验35:使用@Autowired注解实现根据类型实现自动装配★

@Autowired 注解 会自动的根据标注的对象类型在Spring容器中查找相对应的类。如果找到,就自动装配。
使用@Autowired注解,不需要get/set方法

@Service
public class BookService {
/**
* @Autowired 实现自动注入

* 1、先按类型查找并注入

*/
@Autowired
private BookDao bookDao;

@Override
public String toString() {
	return "BookService [bookDao=" + bookDao + "]";
}

}

8.4、多个同类型的bean如何自动装配
实验36:如果资源类型的bean不止一个,默认根据@Autowired注解标记的成员变量名作为id查找bean,进行装配★

bean对象

@Repository
@Scope(“prototype”)
public class BookDao {
}
@Repository
public class BookDaoExt extends BookDao{
}
@Service
public class BookService {
/**
* @Autowired 实现自动注入

* 1、先按类型查找并注入

* 2、如果找到多个,就接着按属性名做为id继续查找并注入

*/
@Autowired
private BookDao bookDao;

@Override
public String toString() {
	return "BookService [bookDao=" + bookDao + "]";
}

}

测试的代码:

@Test
public void test1() throws Exception {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	System.out.println(applicationContext.getBean("bookService"));
}

8.5、使用@Qualifier装配指定id的bean对象
实验37:如果根据成员变量名作为id还是找不到bean,可以使用@Qualifier注解明确指定目标bean的id★

@Service
public class BookService {
/**
* @Autowired 实现自动注入

* 1、先按类型查找并注入

* 2、如果找到多个,就接着按属性名做为id继续查找并注入

* 3、如果找到多个。但是属性名做为id找不到,可以使用@Qualifier(“bookDao”)注解指定id查找并注入

*/
@Autowired
@Qualifier(“bookDaoExt”)
private BookDao bookDao1;

@Override
public String toString() {
	return "BookService [bookDao=" + bookDao1 + "]";
}

}

8.6、@Autowired注解的required属性作用
实验39:@Autowired注解的required属性指定某个属性允许不被设置

@Service
public class BookService {
/**
* @Autowired 实现自动注入

* 1、先按类型查找并注入

* 2、如果找到多个,就接着按属性名做为id继续查找并注入

* 3、如果找到多个。但是属性名做为id找不到,可以使用@Qualifier(“bookDao”)注解指定id查找并注入

* 4、可以通过修改@Autowired(required=false)允许字段值为null
*/
@Autowired(required=false)
@Qualifier(“bookDaoExt1”)
private BookDao bookDao1;

@Override
public String toString() {
	return "BookService [bookDao=" + bookDao1 + "]";
}

}

8.7、@Autowired和@Qualifier在方法上的使用。
实验38:在方法的形参位置使用@Qualifier注解

/**
 * @Autowired标注在方法上,那么此方法会在对象创建之后调用。
 * 		1、先按类型查找参数并调用方法传递<br/>
 * 		2、如果找到多个,就接着按参数名做为id继续查找并注入<br/>
 *		3、如果找到多个。但是参数名做为id找不到,可以使用@Qualifier("bookDao")注解指定id查找并调用<br/>
 *     4、可以通过修改@Autowired(required=false)允许不调用此方法也不报错
 */
@Autowired(required=false)
public void setBookDao(@Qualifier("bookDaoExt1")BookDao abc) {
	System.out.println("BookDao进来啦 --->>> " + abc);
}

8.8、泛型注入(了解内容)
实验40:测试泛型依赖注入★
在这里插入图片描述

9、Spring的扩展的Junit测试
@ContextConfiguration
@RunWith

/**

  • Spring扩展了Junit测试。测试的上下文环境中自带Spring容器。

  • 我们要获取Spring容器中的bean对象。就跟写一个属性一样方便。
    */
    // @ContextConfiguration配置Spring容器
    @ContextConfiguration(locations=“classpath:applicationContext.xml”)
    // @RunWith配置使用Spring扩展之后的Junit测试运行器
    @RunWith(SpringJUnit4ClassRunner.class)
    public class SpringJunitTest {

    @Autowired
    UserService userService;

    @Autowired
    BookService bookService;

    @Test
    public void test1() throws Exception {
    bookService.save(new Book());
    System.out.println("===========================================");
    userService.save(new User());
    }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值