前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring框架的秘密

Spring框架的秘密

作者头像
猫头虎
发布2024-04-07 17:13:56
1100
发布2024-04-07 17:13:56
举报
文章被收录于专栏:猫头虎博客专区

Spring

1. Spring 框架的引言

spring(春天),生于在2002年,由Rod Johnson创作。Spring框架是一个集众多设计模式于一身的开源的轻量级项目管理框架。致力于JAVAEE轻量级解决方案。相对于原来学过的框架而言,spring框架和之前学习的struts2 、 mybatis 框架有了本质的区别,不是替换原来的某个框架,而是对其进行整合管理

轻量级解决方案:提供一个以简单的、统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。


2.Spring 框架的核心作用

Spring 框架用来管理[创建|使用|销毁]项目中的组件,由于spring 框架可以帮我们生产项目中组件对象,因此也习惯称spring是一个工厂|容器

组件: 项目中的service,dao,action,都是项目中的组件 注意: spring框架通常不管理对实体类对象创建


3.Spring 第一个环境搭建

1.引入依赖
代码语言:javascript
复制
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
2.引入配置文件
代码语言:javascript
复制
# 配置文件名称: 任意名称 
# 配置文件位置: 项目中根下任意位置
# 配置文件的内容:
		<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd ">
    </beans>
3.创建组件

userDAO

代码语言:javascript
复制
package com.libin.dao;

public interface UserDAO {
    void save(String name);
}

userDAOImpl

代码语言:javascript
复制
package com.libin.dao;

public class UserDAOImpl implements UserDAO {
    @Override
    public void save(String name) {
        System.out.println("姓名:"+name);
    }
}
4.配置工厂管理组件

spring.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  	<!--通过bean标签管理组件对象-->
    <bean id="userDAO" name="可以重复" class="com.libin.dao.UserDAOImpl"></bean>

</beans>
5.启动工厂测试
代码语言:javascript
复制
 public static void main(String[] args) {
			 //启动工厂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
				//获取对象
        UserDAO userDAO = (UserDAO) context.getBean("userDAO");//如果name,多个重复,最后一个有效

        userDAO.save("晓晓");
    }

4.Spring框架中的核心思想

4.1 IOC[控制反转]

IOC(inversion of controll)控制反转

代码语言:javascript
复制
# 1.定义
	将对象的创建由原来(new)的方式转移到配置文件中,交给spring工厂来创建对象

DI(dependcy Injection)依赖注入

代码语言:javascript
复制
# 1.定义
	Spring不仅要创建对象,还要建立类与类之间的关系,因此在控制反转的基础上又提出了依赖注入的概念。
4.2 AOP[面向切面编程]

AOP( Aspect Oriental Programing ) 面向切面的编程


5.Spring 依赖注入

5.1 SET方式注入

IoC Service Provider通过调用成员变量提供的setter函数将被依赖对象注入给依赖类。 优点:灵活。可以选择性地注入需要的对象。 缺点:依赖对象初始化完成后由于尚未注入被依赖对象,因此还不能使用。

1.对象注入

CityDAO

代码语言:javascript
复制
package com.libin.dao;

public interface CityDAO {
    void query(String name);
}

CityDAOImpl

代码语言:javascript
复制
package com.libin.dao;

public class CityDAOImpl implements CityDAO{
    @Override
    public void query(String name) {
        System.out.println("cityDAO: "+name);
    }
}

CityServiceImpl

代码语言:javascript
复制
package com.libin.service;

public class CityServiceImpl implements CityService{

    //依赖注入
    private CityDAO cityDAO;

    public void setCityDAO(CityDAO cityDAO) {
        this.cityDAO = cityDAO;
    }

    @Override
    public void queryAll(String name) {

        //CityDAO cityDAO = new CityDAOImpl();
        System.out.println("cityServer: "+name);

        cityDAO.query(name);
    }
}

spring.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--DAO组件对象-->
    <bean class="com.libin.dao.CityDAOImpl" id="cityDAOs"></bean>

    <!--Service组件对象-->
    <bean class="com.libin.service.CityServiceImpl" id="cityService">

        <!--  注入:为类中成员变量赋值
            property: 为类中成员变量注入值
            name: 为哪个成员变量注入值   成员变量名
            ref: 用来配置注入对象在工厂中的唯一标识
        -->
        <property name="cityDAO" ref="cityDAOs"></property>
    </bean>
</beans>

测试----TestSpring

代码语言:javascript
复制
public class TestSpring {
    public static void main(String[] args) {
        //启动工厂  工厂启动创建组件对象
        ApplicationContext context = new ClassPathXmlApplicationContext("di/spring.xml");
        //获取工厂中创建的对象  参数:通过在工厂的唯一标识获取
        CityService cityService = (CityService) context.getBean("cityService");
        cityService.queryAll("xiaohuang");
    }
}
2.八种基本类型+String类型 +日期类型的注入
代码语言:javascript
复制
<property name="name" value="zhagnsan"/>
<property name="age" value="21"/>
<property name="id" value="100063"/>
<property name="bir" value="2012/12/12"/>
<property name="price" value="23.23"/>
3.数组类型注入
代码语言:javascript
复制
<!--注入数组类型数据-->
  <property name="qqs">
     <array>
         <value>xxx</value>
         <value>qqq</value>
         <value>vvvv</value>
      </array>
  </property>
4.引用类型和集合类型注入
代码语言:javascript
复制
<!--注入引用类型和对象-->
<property name="userDAO" ref="userDAO"/>
<property name="lists">
  <list>
    <value>aaa</value>
    <value>bbb</value>
    <value>ccc</value>
  </list>
</property>
<property name="maps">
  <map>
    <entry key="aa" value="xiaohei"/>
    <entry key="bb" value="xiaoming"/>
    <entry key="cc" value="xiaosan"/>
  </map>
</property>
<property name="props">
  <props>
    <prop key="url">jdbc:mysql://localhost:3306/test</prop>
    <prop key="driver">com.mysql.jdbc.Driver</prop>
    <prop key="username">hr</prop>
    <prop key="password">hr</prop>
  </props>
</property>

**注意**: 引用类型使用ref属性注入,基本类型使用value属性注入


5.2.构造注入

定义:使用类中的构造方法为成员变量注入值的过程称之为构造注入 语法: ​ a.依赖:需要谁将谁声明为成员变量并提供公开构造方法 ​ b.注入:在配置文件中使用进行注入

将被依赖对象通过构造函数的参数注入给依赖对象,并且在初始化对象的时候注入。 优点:对象初始化完成后便可获得可使用的对象。 缺点:当需要注入的对象很多时,构造器参数列表将会很长; 不够灵活。若有多种注入方式,每种方式只需注入指定几个依赖,那么就需要提供多个重载的构造函 数,麻烦。

StudentDAOmpl.java

代码语言:javascript
复制
package constructor;

public class StudentDAOImpl implements StudentDAO {
    @Override
    public void querys(String name) {
        System.out.println("===querys==dao="+name);
    }
}

StudentServiceImpl.java

代码语言:javascript
复制
package constructor;

public class StudentServiceImpl implements StudentService {

    //依赖注入声明成员变量
    private StudentDAO studentDAO;

    //提供构造方法
    public StudentServiceImpl(StudentDAO studentDAO) {
        this.studentDAO = studentDAO;
    }

    @Override
    public void querys(String name) {
        System.out.println("===querys=service==");
        studentDAO.querys(name);
    }
}

spring.xml

代码语言:javascript
复制
<bean class="autodi.StudentDAOImpl" id="studentDAO"></bean>

<bean class="autodi.StudentServiceImpl" id="studentService">
    <constructor-arg index="0" name="studentDAO" ref="studentDAO"></constructor-arg>
</bean>

测试

代码语言:javascript
复制
package constructor;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("constructor/spring.xml");
        StudentService studentService = (StudentService) context.getBean("studentService");
        studentService.querys("晓晓");
    }
}

注入其他属性

代码语言:javascript
复制
<!--使用构造方法注入对象-->
<constructor-arg index="0" name="id" ref="user"/>

<!--使用基本数据类型注入值-->
<constructor-arg index="0" name="id" value="1"/>
<constructor-arg index="1" name="name" value="xiaohei"/>
<constructor-arg index="2" name="age" value="12"/>
<constructor-arg index="3" name="qqs">
    <array>
        <value>xxx</value>
        <value>222</value>
        <value>333</value>
    </array>
</constructor-arg>

注意:构造注入并不常用,不过在一些框架类中必须使用构造注入,这里先了解其注入语法即可。

5.3.自动注入

自动注入对象 语法: ​ 1.依赖:需要谁将谁声明为成员变量并提供公开的Set方法 ​ 2.注入:在配置文件中的bean标签,使用autowired属性 原理:底层使用SET方式注入 注意:只能自动完成组件对象之间的注入 不能注入八种基本类型 + String + Date + List + 数组 + Map

autowire : 为类中成员变量自动注入值

  • autowire=”byName”

根据注入的属性名与配置文件中bean的id匹配,一致则注入,不一致报错

  • autowire=”byType”

根据注入的属性类型,与配置文件中的类型匹配,类型一致注入(在多个实现类时,会产生歧义) 注意: 无论使用以上那种方式注入都需要为属性提供set方法

StudentDAOmpl.java

代码语言:javascript
复制
package autodi;

public class StudentDAOImpl implements StudentDAO {
    @Override
    public void querys(String name) {
        System.out.println("===querys==dao="+name);
    }
}

StudentServiceImpl.java

代码语言:javascript
复制
package autodi;

public class StudentServiceImpl implements StudentService {

    //依赖注入声明成员变量
    private StudentDAO studentDAO;
    //提供公开的set方法
    public void setStudentDAO(StudentDAO studentDAO) {
        this.studentDAO = studentDAO;
    }

    @Override
    public void querys(String name) {
        System.out.println("===querys=service==");
        studentDAO.querys(name);
    }
}

spring.xml

代码语言:javascript
复制
<bean class="autodi.StudentDAOImpl" id="studentDAO"></bean>

<bean class="autodi.StudentServiceImpl" id="studentService" autowire="byType"></bean>

测试

代码语言:javascript
复制
package constructor;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("autodi/spring.xml");
        StudentService studentService = (StudentService) context.getBean("studentService");
        studentService.querys("晓晓");
    }
}

6.Spring 的Bean工厂

6.1.bean的创建模式

singleton:单例 默认

​ 在工厂中全局唯一,只创建一次

prototype: 多例

全局不唯一,每次使用都会创建一个新的对象

代码语言:javascript
复制
<bean id="" class="xxxx.userAction" scope="prototype|singleton">
		service,dao    ----->  singleton
		struts2 action -----> prototype

注意:在项目开发中service,dao组件单例,struts2的Action必须为:多例


6.2.bean的生产原理

原理: 反射+构造方法

代码语言:javascript
复制
 UserDAOImpl userDAO = (UserDAOImpl) Class.forName("com.libin.dao.UserDAOImpl").newInstance();
 System.out.println(userDAO);

6.3.bean的生命周期

  • 何时创建 随着工厂启动, 所有单例bean随之创建 非单例的bean,每次使用时创建
  • 何时销毁 工厂**关闭,所有bean随之销毁** ( 注意: spring对多例bean管理松散,不会负责多例bean的销毁)
6.4.bean工厂创建对象的好处

  1. 使用配置文件管理java类,再生产环境中更换类的实现时不需要重新部署,修改文件即可
  2. spring默认使用单例的模式创建bean,减少内存的占用
  3. 通过依赖注入建立了类与类之间的关系(使java之间关系更为清晰,方便了维护与管理)

Day2

1.现有业务层开发存在问题

a.定义业务接口
代码语言:javascript
复制
public interface UserService {
    void save(String name);
    void delete(String id);
    void update();
    String findAll(String name);
    String findOne(String id);
}
b.实现业务接口
代码语言:javascript
复制
public class UserServiceImpl implements UserService {
    @Override
    public void save(String name) {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void delete(String id) {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void update() {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public String findAll(String name) {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return name;
    }

    @Override
    public String findOne(String id) {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return id;
    }
}

问题:从上图中可以看出,现有业务层中控制事务代码出现了大量的冗余,如何解决现有业务层出现的冗余问题?


2.代理引言

a.什么是代理

代理: 指的是java中的一种设计模式

b.为什么需要代理

很多时候除了当前类能够提供的功能外,我们还需要补充一些额外功能。

c.代理的作用

代理对象可以在客户和目标对象之间起到中介作用,从而为目标对象增添额外的功能

d.代理图例

3.静态代理的开发

目标类|对象(target):被代理类称之为目标类|或者被代理的对象的称之为目标对象 开发代理的原则: 代理类和目标类功能一致且实现相同的接口,同时代理类中依赖于目标类对象

a.开发静态代理类
代码语言:javascript
复制
//静态代理类
//开发原则:代理类和目标类实现相同接口,依赖于真正的目标类
public class UserServiceStaticProxy implements UserService {

    //真正的目标类 //target 原始业务逻辑对象
    private UserService userService;
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void save(String name) {
        try {
            System.out.println("开启事务");
            userService.save(name);//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void delete(String id) {
        try {
            System.out.println("开启事务");
            userService.delete(id);//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void update() {
        try {
            System.out.println("开启事务");
            userService.update();//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public String findAll(String name) {
        try {
            System.out.println("开启事务");
            String result = userService.findAll(name);//调用真正业务逻辑方法
            System.out.println("提交事务");
            return result;
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String findOne(String id) {
        try {
            System.out.println("开启事务");
            //调用目标类方法
            String one = userService.findOne(id);//调用真正业务逻辑方法
            System.out.println("提交事务");
            return one;
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return null;
    }
}
b.更改目标实现类
代码语言:javascript
复制
public class UserServiceImpl implements UserService {
    @Override
    public void save(String name) {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public void delete(String id) {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public void update() {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public String findAll(String name) {
        System.out.println("处理业务逻辑,调用DAO~~~");
        return name;
    }

    @Override
    public String findOne(String id) {
        System.out.println("处理业务逻辑,调用DAO~~~");
        return id;
    }
}
c.配置静态代理类
代码语言:javascript
复制
		<!--配置目标类-->
    <bean id="userService" class="staticproxy.UserServiceImpl"></bean>

    <!--配置代理类-->
    <bean id="userServiceStaticProxy" class="staticproxy.UserServiceStaticProxy">
        <!--注入目标对象-->
        <property name="userService" ref="userService"/>
    </bean>
d.调用代理方法
代码语言:javascript
复制
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userServiceStaticProxy = (UserService) context.getBean("userServiceStaticProxy");
userServiceStaticProxy.save("晓晓");

新的问题:往往在开发我们书写的不仅仅是一个业务层,两个业务层,而我们的业务层会有很多,如果为每一个业务层开发一个静态代理类,不仅没有减轻工作量,甚至让我们的工作量多了一倍不止怎么解决以上这个问题呢? 解决方案: 为业务层在运行过程中动态创建代理类,通过动态代理类去解决我们现有业务层中业务代码冗余的问题 .


4.动态代理的原理

通过jdk提供的Proxy这个类,动态为现有的业务生成代理类 参数一:当前线程类加载器 参数二:生成代理类的接口类型 参数三:通过代理类对象调用方法时会优先进入参数三中的invoke方Proxy.newProxyInstance(loader, interfaces, h);//返回值就是动态代理对象

代码语言:javascript
复制
public class TestDynamicProxy {
    public static void main(String[] args) {
        final UserService userService =  new UserServiceImpl();
        //参数1:当前线程类加载器
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        //参数2:
        Class[] classes =  new Class[]{UserService.class};
        //参数3:
        UserService userServiceProxy = (UserService) Proxy.newProxyInstance(contextClassLoader, classes, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                try{
                    System.out.println("开启事务");//附加操作
                    Object invoke = method.invoke(userService, args);
                    System.out.println("提交事务");//附加操作
                    return invoke;
                }catch (Exception e){
                    System.out.println("回滚事务");//附加操作
                }
                return null;
            }
        });
        userServiceProxy.save("小晓");
    }
}

5.AOP (Aspect Oriented Programming)编程

通知(Advice): 除了目标方法以外的操作都称之为通知 切入点(PointCut): 要为哪些类中的哪些方法加入通知 切面(Aspect): 通知 + 切入点

1.通知分类
2.编程步骤
代码语言:javascript
复制
# 1.引入依赖
	 spring-aop
	 spring-expression
	 spring-aspects

# 2.开发通知类
	  MethodBeforeAdvice      前置通知
	  MethodInterceptor       环绕通知
	  AfterReturningAdvice    返回后通知
	  ThrowsAdvice						异常通知
	  
	  MyAdvice implements  通知接口{.....}
	  
    //自定义通知类:用来完成额外功能
    public class MyAdvice  implements MethodBeforeAdvice {
        @Override//参数1:当前调用的方法对象    //参数2:当前调用方法对象的参数  //参数3:目标对象
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println("目标方法名: "+method.getName());
            System.out.println("目标方法的参数: "+objects);
            System.out.println("目标对象: "+o.getClass());
        }
    }
# 3.配置切面
		a.引入aop命名空间
 			 <?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
       		                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
		b.管理通知
			 <!--管理通知类-->
    	 <bean id="myAdvice" class="before.MyAdvice"/>
   	c.配置切面
   		<aop:config>
        <aop:pointcut id="pc" expression="execution(* before.UserServiceImpl.*(..))"/>
        <aop:advisor advice-ref="myAdvice" pointcut-ref="pc"/>
    	</aop:config>

# 4.启动工厂测试
		 		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("before/spring.xml");
        UserService userSerivce = (UserService) context.getBean("userService");
        System.out.println(userSerivce.getClass());
        userSerivce.save("晓晓");
3.前置通知的使用
4.环绕通知的使用
5.返回后通知
6.异常通知

6.切入点表达表

1.execution方法级别的切入点表达式

注意:方法级别的切入点表达式尽可能精准,否则程序运行可能出现异常

2.within类级别的切入点表达式
代码语言:javascript
复制
# 1.语法
	within(包.类)

# 2.示例
	within(com. service.*) 
			包: com. service
			类: 所有类中所有方法不关心返回值和参数
	
	within(com. service.UserServiceImpl)
			包: com.libin.service
			类: UserServiceImpl类中所有方法不关心返回值和参数

注意:within的效率高于execution表达式,推荐使用within表达式

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring
    • 1. Spring 框架的引言
      • 2.Spring 框架的核心作用
        • 3.Spring 第一个环境搭建
          • 1.引入依赖
          • 2.引入配置文件
          • 3.创建组件
          • 4.配置工厂管理组件
          • 5.启动工厂测试
        • 4.Spring框架中的核心思想
          • 4.1 IOC[控制反转]
          • 4.2 AOP[面向切面编程]
        • 5.Spring 依赖注入
          • 5.1 SET方式注入
          • 5.2.构造注入
          • 5.3.自动注入
        • 6.Spring 的Bean工厂
          • 6.1.bean的创建模式
          • 6.2.bean的生产原理
          • 6.3.bean的生命周期
          • 6.4.bean工厂创建对象的好处
      • Day2
        • 1.现有业务层开发存在问题
          • a.定义业务接口
          • b.实现业务接口
        • 2.代理引言
          • a.什么是代理
          • b.为什么需要代理
          • c.代理的作用
          • d.代理图例
        • 3.静态代理的开发
          • a.开发静态代理类
          • b.更改目标实现类
          • c.配置静态代理类
          • d.调用代理方法
        • 4.动态代理的原理
          • 5.AOP (Aspect Oriented Programming)编程
            • 1.通知分类
            • 2.编程步骤
            • 3.前置通知的使用
            • 4.环绕通知的使用
            • 5.返回后通知
            • 6.异常通知
          • 6.切入点表达表
            • 1.execution方法级别的切入点表达式
            • 2.within类级别的切入点表达式
        相关产品与服务
        项目管理
        CODING 项目管理(CODING Project Management,CODING-PM)工具包含迭代管理、需求管理、任务管理、缺陷管理、文件/wiki 等功能,适用于研发团队进行项目管理或敏捷开发实践。结合敏捷研发理念,帮助您对产品进行迭代规划,让每个迭代中的需求、任务、缺陷无障碍沟通流转, 让项目开发过程风险可控,达到可持续性快速迭代。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档