Spring学习笔记(二)

六、对象的生命周期

6.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();
	}

6.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();
	}

七、Spring管理数据库连接池(重点)

7.1、Spring配置管理数据库连接池对象(重点)

导入jar
在这里插入图片描述
applicationContext.xml配置:

	<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() );
		
	}

7.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配置文件:

	<!-- 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>

7.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配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!--<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">-->

<!-- 标签用来代替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>
</beans>

八、Spring EL表达式(了解内容)

创建java实体Bean对象


public class Person {

    private Integer id;
    private String name;

    private Car car;

    public Person() {
    }

    public Person(Integer id, String name, Car car) {
        this.id = id;
        this.name = name;
        this.car = car;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", car=" + car +
                '}';
    }
}

public class Car {

	public class Car {

    private String carNo;
    private String name;

    public static String staticFun(){
        return "staticFun";
    }

    public String fun(){
        return "funName";
    }

    public Car() {
    }

    public Car(String carNo, String name) {
        this.carNo = carNo;
        this.name = name;
    }

    public String getCarNo() {
        return carNo;
    }

    public void setCarNo(String carNo) {
        this.carNo = carNo;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "carNo='" + carNo + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

applicationContext.xml配置:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util-4.0.xsd">


    <bean id="car" class="com.atguigu.bean.Car" >
        <property name="carNo" value="京B123412" />
        <property name="name" value="蓝脖鸡泥" />
    </bean>

    <!-- 实验26:[SpEL测试I]在SpEL中使用字面量 -->
    <!-- 使用格式:#{数值} 		#{“字符串” || ‘字符串’} -->
    <bean id="p1" class="com.atguigu.bean.Person">
        <property name="id" value="#{100}" />
        <property name="name" value="#{'我是SpringEL输出的字符串'}" />
    </bean>

    <!-- 实验27:[SpEL测试II]在SpEL中引用其他bean -->
    <!-- 使用格式:#{bean的id} -->
    <bean id="p2" class="com.atguigu.bean.Person">
        <property name="id" value="#{100}" />
        <property name="car" value="#{car}" />
    </bean>


    <!-- 实验28:[SpEL测试III]在SpEL中引用其他bean的某个属性值 -->
    <!-- 使用格式: #{bean.属性名} -->
    <bean id="p3" class="com.atguigu.bean.Person">
        <property name="name" value="#{car.name}" />
    </bean>

    <!-- 实验29:[SpEL测试IV]在SpEL中调用非静态方法 -->
    <!-- 使用格式: #{bean.方法名(参数)} -->
    <bean id="p4" class="com.atguigu.bean.Person">
        <property name="name" value="#{car.fun()}" />
    </bean>


    <!-- 实验30:[SpEL测试V]在SpEL中调用静态方法 -->
    <!-- 使用格式:#{T(全名类).方法名(参数)} -->
    <bean id="p5" class="com.atguigu.bean.Person">
        <property name="name" value="#{T(com.atguigu.bean.Car).staticFun()}" />
    </bean>

    <!-- 实验31:[SpEL测试VI]在SpEL中使用运算符 -->
    <!-- 使用格式:#{表达式} -->
    <bean id="p6" class="com.atguigu.bean.Person">
        <property name="id" value="#{100 * 10}" />

    </bean>

</beans>



测试



import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Persontest {

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

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

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

    @Test
    public void test4(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println( applicationContext.getBean("p4") );
    }

    @Test
    public void test5(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println( applicationContext.getBean("p5") );
    }

    @Test
    public void test6(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println( applicationContext.getBean("p6") );
    }

}


九、注解功能(极其重要)

9.1、注解配置Dao、Service、Controller组件

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

bean对象

/**
 * @Component 注解表示<br/>
 * <bean id="book" class="com.atguigu.pojo.Book" />
 */
@Component
public class Book {
}

/**
 * @Repository 注解表示<br/>
 * <bean id="bookDao" class="com.atguigu.dao.BookDao" /><br/>
 * @Repository("abc") 表示
 * <bean id="abc" class="com.atguigu.dao.BookDao" /><br/>
 */
@Repository
@Scope("prototype")
public class BookDao {
}
/**
 * @Service 注解表示<br/>
 * <bean id="bookService" class="com.atguigu.service.BookService" />
 */
@Service
public class BookService {
}
/**
 * @Controller 注解表示<br/>
 * <bean id="bookController" class="com.atguigu.controller.BookController" />
 */
@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"));

	}

9.2、指定扫描包时的过滤内容

实验33:使用context:include-filter指定扫描包时要包含的类
实验34:使用context:exclude-filter指定扫描包时不包含的类

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

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

类别示例说明
annotationcom.atguigu.XxxAnnotation过滤所有标注了XxxAnnotation的类。这个规则根据目标组件是否标注了指定类型的注解进行过滤
assignablecom.atguigu.BaseXxx过滤所有BaseXxx类的子类。这个规则根据目标组件是否是指定类型的子类的方式进行过滤。
aspectjcom.atguigu.*Service+所有类名是以Service结束的,或这样的类的子类。这个规则根据AspectJ表达式进行过滤.
regexcom.atguigu.anno.*所有com.atguigu.anno包下的类。这个规则根据正则表达式匹配到的类名进行过滤。
customcom.atguigu.XxxTypeFilter使用XxxTypeFilter类通过编码的方式自定义过滤规则。该类必须实现org.springframework.core.type.filter.TypeFilter接口

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>

9.3、使用注解@Autowired自动装配

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

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

@Service
public class BookService {
	/**
	 * @Autowired 实现自动注入<br/>
	 * 	1、先按类型查找并注入<br/>
	 */
	@Autowired
	private BookDao bookDao;

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

}

9.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 实现自动注入<br/>
	 * 	1、先按类型查找并注入<br/>
	 *  2、如果找到多个,就接着按属性名做为id继续查找并注入<br/>
	 */
	@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"));
	}

9.5、使用@Qualifier装配指定id的bean对象

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

@Service
public class BookService {
	/**
	 * @Autowired 实现自动注入<br/>
	 * 	1、先按类型查找并注入<br/>
	 *  2、如果找到多个,就接着按属性名做为id继续查找并注入<br/>
	 *  3、如果找到多个。但是属性名做为id找不到,可以使用@Qualifier("bookDao")注解指定id查找并注入<br/>
	 */
	@Autowired
	@Qualifier("bookDaoExt")
	private BookDao bookDao1;

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

}


9.6、@Autowired注解的required属性作用

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

@Service
public class BookService {
	/**
	 * @Autowired 实现自动注入<br/>
	 * 	1、先按类型查找并注入<br/>
	 *  2、如果找到多个,就接着按属性名做为id继续查找并注入<br/>
	 *  3、如果找到多个。但是属性名做为id找不到,可以使用@Qualifier("bookDao")注解指定id查找并注入<br/>
	 *  4、可以通过修改@Autowired(required=false)允许字段值为null
	 */
	@Autowired(required=false)
	@Qualifier("bookDaoExt1")
	private BookDao bookDao1;

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

}

9.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);
	}

9.8、泛型注入(了解内容)

实验40:测试泛型依赖注入★

在这里插入图片描述

十、Spring的扩展的Junit测试

@ContextConfiguration
@RunWith

/**
 * Spring扩展了Junit测试。测试的上下文环境中自带Spring容器。<br/>
 * 我们要获取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、付费专栏及课程。

余额充值