IOC和Aop机制
Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
如上图,A需要调用B原先的逻辑是,在A的对象内,生成一个B的实例。
具体实现:
class A{
@Autowired
B b;
public void doA(){
b.doA();
}
}
@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,用户在方法切面的开始或者结束部分,插入语句。
第一行代码
- 访问 Springboot脚手架 https://start.spring.io/
- 选择需要的依赖Dependency,(注意:Springboot本身不包括web模块)常见的包括web、aspect(面向切片编程)、jpa(hibernate)、Thymeleaf(模板语言)等。
- 点击“generate project”生成zip压缩包。 在eclipse中导入->maven project->选择解压后的文件夹->完成导出。
- 导入完成后,eclipse会自动下载相关依赖并编译。
- 选择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 A getA(){
return new A();
}
}
注意,Configuration是必要的。
而在定义自动注入的同时,则使用@Autowired进行注入,这里就会有个疑问,如果存在两个相同名称的类型,Spring框架注入哪个类型。
通常的解决方法是 @Resource(“name”),注意@Resource是按名称进行的注入,而@Autowired是根据类型进行注入。
这里有个问题,利用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");
}