Spring boot 概要

IOC和Aop机制

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

new
对象A
对象B

如上图,A需要调用B原先的逻辑是,在A的对象内,生成一个B的实例。

存储
获取
对象B
BeanFactory
对象A

具体实现:


class A{
	@Autowired
	B b;
	public void doA(){
		b.doB();
	}
}

@Component
class B{
	public void doB(){
	}
}

而在Springboot内,为了减少A直接调用B,减少他们之间的耦合性,在框架内定义了BeanFactory,在Springboot程序初始化的时候,对象B注入到BeanFactory中(注:这里可以把BeanFactory看做是一个抽象的工厂)。
而当A在调用的同时,将从BeanFactory获取B的对象实例。
利用BeanFactory机制,用户可以采用动态代理对对象B实现切片编程,也就是AOP(面向切面编程)。

Aop——Aspect Oriented Programming,面向切面编程。通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。用户可以利用Aop实现日志记录,方法拦截,以及事务@Transactional中也用到了Aop机制。

具体实现:

@Component
@Aspect
public class Operator {
    
    @Pointcut("execution(* com.aijava.springcode.service..*.*(..))")
    public void pointCut(){}
    
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("AOP Before Advice...");
    }
    
    @After("pointCut()")
    public void doAfter(JoinPoint joinPoint){
        System.out.println("AOP After Advice...");
    }
}

通过Aop,用户在方法切面的开始或者结束部分,插入语句。

为什么要使用IOC

1.为了降低代码间的耦合,我们常采用接口的方式进行通讯,如

Interface A{
	public void methodA();
}
Class AImp{
	public void methodA(){
		System.out.println("DoA";
	}
}
Class B{
	public static void main(String args[]){
		A a =new AImp();
	}
}

通常情况下,都是采用 A a=new AImp();的方式,进行初始化,但是这种情况下,B不仅对接口A产生耦合,对AImp的实现也有耦合,如果在一些场景下,我的需求产生了变化,我需要变动A的需求,根据开放封闭原则,我们需要对A进行扩展而不是直接修改A,那我们可能会写一个新的类AplusImp来代替AImp,如果不采用依赖注入的方式,我们需要寻找所有A的实现,并替换成A a=new AplusImp()。而采用依赖注入方式

Interface A{
	public void methodA();
}
@Component
Class AImp{
	public void methodA(){
		System.out.println("DoA";
	}
}
@Primary
@Component
Class AplusImp{
	public void methodA(){
		System.out.println("DoA";
	}
}
Class B{
	@Autowired
	A a;
	public static void main(String args[]){

	}
}

如图,我只需要增加一个新的类AplusImp,标记@Primary即可实现对A的实现替换。
2.Aop的注入都是依赖于IOC机制,直接new一个新的变量无法实现对代码的切面编程。

Aop使用场景

Authentication 权限、Caching 缓存、Context passing 内容传递、Error handling 错误处理、Lazy loading 懒加载、Debugging 调试、logging, tracing, profiling and monitoring 记录跟踪 优化 校准、Performance optimization 性能优化、Persistence 持久化、Resource pooling 资源池、Synchronization 同步、Transactions 事务

第一行代码

  1. 访问 Springboot脚手架 https://start.spring.io/
  2. 选择需要的依赖Dependency,(注意:Springboot本身不包括web模块)常见的包括web、aspect(面向切片编程)、jpa(hibernate)、Thymeleaf(模板语言)等。
  3. 点击“generate project”生成zip压缩包。 在eclipse中导入->maven project->选择解压后的文件夹->完成导出。
  4. 导入完成后,eclipse会自动下载相关依赖并编译。
  5. 选择App.java->run as ->Java Application

相关配置

默认在src/main/resources下会有application.properties文件,详细的配置内容可参考 https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-configure-datasource 网页下的Part X. Appendices部分
这里简单强调下常用的配置文件包括:

server.port http=80#端口号
spring.datasource.* =???#连接数据库常用配置,包括用户名密码,url和driver-class
logging.* =???#日志相关
spring.jpa.*=??? #jpa相关配置

注入实现

如之前的图片所示,依赖注入存放在BeanFactory中,而如何识别需要注入的对象,则是通过@Component实现,实际上,@Component、@Service、@Repository都可以实现需要注入对象的标记。上述注释在作用上完全相同,但是为了区别实际代码功能,将他们区分为 组件、服务、和数据仓库。除了上述实现方式,Spring也可以通过@Bean实现依赖注入

@Configuration
class Common{
	@Bean
	public B getB(){
		return new B();
	}
	static class B{
		public void doB(){
			System.out.println("doB");
		}
	}
}
class A{
   @Autowired
   B b;
   public void doA(){
   	b.doB();
   }
}

注意,Configuration是必要的。
而在定义自动注入的同时,则使用@Autowired进行注入,这里就会有个疑问,如果存在两个相同名称的类型,Spring框架注入哪个类型。
通常的解决方法是 @Resource(“name”),注意@Resource是按名称进行的注入,而@Autowired是根据类型进行注入。
当然在@Autowired,增加@Qualifier注释指定注入的名称,也可以实现和@Resource相同的效果。
这里有个问题,利用Springboot实现的多次注入是同一个对象么,例如:

@Component
class A{
	int i=1;
}
class B{
	@Autowired
	A a1;
	@Autowired
	A a2;
	public void IsSame(){
		System.out.println(a1==a2);//输出true
	}
}

实际上最终返回的结果是true,也就是说,默认的类型A都是以单例模式保存到BeanFactory中,每次@Autowired注入的都是同样的对象。那如果需要每次生成一个新类怎么办,@Scope就能解决问题,如下:

@Component
@Scope("prototype")
class A{
  int i=1;
}
class B{
  @Autowired
  A a1;
  @Autowired
  A a2;
  public void isSame(){
  	System.out.println(a1==a2);//输出false
  }
}

上面表示的是原型模式,原型模式下每次生成的都是一个新的类。

Spring Mvc

如果你学会了之前的内容,之后的知识可能会比较简单了。
不同于Struts2,SpringMvc下不需要配置xml文件,在类名上标记@Controller或@RestController即可。对于网页的url定位可以通过@PostMapping @RequestMapping和@GetMapping进行实现,对于post或get请求中的数据,可以直接声明在参量中,请求view模板文件可以通过返回ModelAndView来实现。

@RestController
public class MainController {
   @GetMapping("/login")
   public ModelAndView getlogin(HttpServletRequest request,Model model) {
   	return new ModelAndView("login");
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值