sping两大核心:IOC(控制反转)、AOP(面向切面)

IOC:创建对象的过程由spring负责,用于解耦(xml方式管理Bean)

  1. IOC底层原理:**xml解析+工厂模式+反射;**<br /> DI:依赖注入,注入属性,是IOC的具体实现,必须在**创建对象的基础**上进行

spring有两种bean:

  1. 1.普通bean,在配置文件的class属性中定义的的类型就是返回类型<br /> 2.工厂bean,在配置文件中定义的类型可以和返回类型不一样(就是可以生成beanbean)

spring的bean默认是单实例对象(bean通过getbean得到的一直是同一个对象),可以通过bean标签的属性scope属性设置为多实例。

  1. 1.singleton,默认,单实例,在**加载spring配置文件**时就会创建对象
  1. <bean id="mybean" class="com.factoryBean.MyBean" scope="singleton"/>
  1. 2.prototype,多实例,在**调用getBean()**时才会创建多实例对象
  1. <bean id="mybean" class="com.factoryBean.MyBean" scope="prototype"/>

Bean生命周期

1.通过构造器创建Bean实例
2.为Bean的属性设值和对其他Bean的引用(set)
init-method=”initMethod”:指定初始化方法
destroy-method=”destroyMethod”:指定销毁方法

  1. <bean id="orders" class="com.beanLife.Orders" init-method="initMethod" destroy-method="destroyMethod">
  2. <property name="name" value="手机"/>
  3. </bean>

3.调用Bean中初始化方法(需要配置)

  1. //自定义初始化方法
  2. public void initMethod(){
  3. System.out.println("初始化方法被调用");
  4. }

4.获取到Bean对象

  1. ApplicationContext applicationContext=new ClassPathXmlApplicationContext("BeanLife.xml");
  2. Orders orders = applicationContext.getBean("orders", Orders.class);
  3. System.out.println("获取到bean对象");

5.当容器关闭调用Bean的销毁方法(需要配置)

  1. //自定义销毁方法
  2. public void destroyMethod(){
  3. System.out.println("销毁方法被调用");
  4. }
  1. //手动调用销毁方法
  2. ((ClassPathXmlApplicationContext)applicationContext).close();

结果:
image.png
加上后置处理器(BeanPostProcessor)一共有7步操作,在原第3步初始化的前后各增加一步,即:
1.通过构造器创建Bean实例
2.为Bean的属性设值和对其他Bean的引用(set)
3.把Bean传递bean前置处理器postProcessBeforeInitialization()
4.调用Bean中初始化方法(需要配置)
5.把Bean传递bean后置处理器postProcessAfterInitialization()
6.获取到Bean对象
7.当容器关闭调用Bean的销毁方法(需要配置)
其中,会为当前配置文件中所有Bean都添加后置处理器

  1. public class MyBeanPost implements BeanPostProcessor {
  2. @Override
  3. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  4. System.out.println("初始化之前的方法");
  5. return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
  6. }
  7. @Override
  8. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  9. System.out.println("初始化之后的方法");
  10. return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
  11. }
  12. }
  1. <!--配置后置处理器-->
  2. <bean id="mybeanpost" class="com.beanLife.MyBeanPost"/>

image.png

注解方式管理Bean

1.针对创建对象提供注解

@Component
@Service :service层
@Controller:web层
@Repository:dao层
以上四个注解功能一样,都用于创建Bean对象,只是使用的层次不同,但是也可以跨层混用

2.创建Bean

2.1引入依赖

image.png

2.2开启组件扫描,告诉Spring哪些类使用注解

创建名称空间
xmlns:context=”http://www.springframework.org/schema/context”
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  5. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  6. </beans>

开启组件扫描

  1. <!-- 开启组件扫描
  2. 1.想扫描多个包可以用逗号隔开或者选择上层目录
  3. -->
  4. <context:component-scan base-package="com.spring5.dao,com.spring5.service"/>

其他方式

  1. <context:component-scan base-package="com.spring5.dao,com.spring5.service" use-default-filters="false">
  2. <!-- 表示不使用默认过滤器,只扫描带Component注解的类-->
  3. <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
  4. </context:component-scan>
  1. <context:component-scan base-package="com.spring5.dao,com.spring5.service">
  2. <!--表示不扫描带Component注解的类-->
  3. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
  4. </context:component-scan>

编写类,为类加注解

  1. /**
  2. * 在注解里写id名字可以省略不写,默认是类名首字母小写
  3. */
  4. @Component(value = "userService") //和xml配置类似
  5. public class UserService {
  6. public void add(){
  7. System.out.println("service add");
  8. }
  1. /**
  2. * 测试注解形式创建bean
  3. */
  4. @Test
  5. public void test1(){
  6. ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean1.xml");
  7. UserService userService = applicationContext.getBean("userService", UserService.class);
  8. userService.add();
  9. }

3.属性注入

@Autowired:根据属性类型自动注入
@Qualifier:根据属性名自动注入,和@Autowired一起使用
@Resource:既可以根据属性类型自动注入,也可以根据属性名自动注入,@Resource注解是javax.annotacion包下的,属于java的扩展包,在标准jdk中没有
@Value:注入普通类型

1.创建service和dao类,并加上注解创建bean

  1. @Repository(value = "userDaoImpl1")
  2. public class UserDaoImpl implements UserDao {
  3. @Override
  4. public void add() {
  5. System.out.println("userDao add");
  6. }
  7. }
  1. @Service(value = "userService") //和xml配置类似
  2. public class UserService {
  3. //添加属性注解@Autowired根据类型注入,不需要写set方法
  4. @Autowired
  5. private UserDao userDao;
  6. public void add(){
  7. System.out.println("service add");
  8. userDao.add();
  9. }
  10. }

2.为service定义dao属性,在属性上加入注解

  1. //添加属性注解@Autowired根据类型注入,不需要写set方法
  2. //@Resource(name="userDaoImpl1"),@Resource注解是javax.annotacion包下的,属于java的扩展包,在标准jdk中没有
  3. @Autowired
  4. //根据名称注入,当一个接口有多个实现类时,确定不了是哪个类,根据名称就可以指定,value等于那个bean的id
  5. @Qualifier(value = "userDaoImpl1")
  6. private UserDao userDao;

4.纯注解开发

1.创建配置类,替代xml文件

  1. /**
  2. * 配置类,取代xml配置文件,实现纯注解开发
  3. */
  4. @Configuration //需要加上这个注解才能作为配置类
  5. @ComponentScan(basePackages = {"com.spring5.dao","com.spring5.service"}) //这个注解实现了组件扫描功能
  6. public class SpringConfig {
  7. }

2.编写测试方法,这里需要实例化AnnotationConfigApplicationContext类实现

  1. /**
  2. * 测试纯注解开发
  3. */
  4. @Test
  5. public void test2(){
  6. //这里需要使用AnnotationConfigApplicationContext实现
  7. ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);
  8. UserService userService = applicationContext.getBean("userService", UserService.class);
  9. userService.add();
  10. }