Sping框架的IOC特性 悲观锁、乐观锁 Spring的AOP特性
IOC(Inversion of Control):控制反转
以下以课程与老师的安排来介绍控制反转。
一个合理的课程编排系统应该围绕培训的内容为核心,而不应该以具体的培训老师为核心,这样才能在正常授课时可以随意选取合适的老师来上课,而非绑定到一个老师身上。
一、探索IOC
1、最紧耦合度的编法

public class JavaTrad { public void JavaCourse(){ Bill bill=new Bill();//引入讲师,使讲师直接侵入培训 bill.teach("Spring IoC章节!"); } }

public class Bill { public void teach(String saying){ System.out.println(saying); } }
老师和课程一一对应,完全耦合,无法做到将代码重心放到课程内容上,而且每次修改讲师后,需要修改源码。
2、较紧耦合度接口式编法
public interface Teacher { public void teach(String saying); }
public class Bill implements Teacher{ @Override public void teach(String saying){ System.out.println(saying); } }
public class JavaTrad { public void JavaCourse(){ Teacher teacher=new Bill();//引入教师接口 teacher.teach("Spring IoC章节!");//通过接口进行授课 } }
Bill讲师实现Teacher接口,利用多态特性,在课程类中让Bill讲师实现Teacher接口。但是这样的话课程类就得和Teacher接口、Bill讲师类都关联,并没有达到我们所期望的授课内容仅依赖与课程类的目的。
所以我们仍然需要找到一个方法来松耦合。
3、引入中介类chairman来松耦合
public interface Teacher { public void teach(String saying); }
public class Bill implements Teacher{ public void teach(String saying){ System.out.println(saying); } }

public class JavaTrad{ private Teacher teacher; public void javaCourse(){ teacher.teach("Spring IoC章节!"); } public void injectTeacher(Teacher teacher) {//聚合 // TODO Auto-generated method stub this.teacher=teacher; } }


public class Chairman { public void managerCourse(){ Teacher teacher=new Bill(); JavaTrad javatrad=new JavaTrad(); javatrad.injectTeacher(teacher); javatrad.javaCourse(); } public static void main(String[] args) { new Chairman().managerCourse(); } }

课程类中只需要引入一个实现老师接口的对象即可,具体是哪个对象实现了老师接口,课程类不用管,这个工作交给了chairman类来分配,解决了具体讲师类和课程类之间的紧耦合关系,但是每次换讲师之前还得修改chairman代码,所以还可以有所改进。
二、IoC概念
在实际应用开发中,需要尽量避免和降低对象之间的依赖关系,即降低耦合,一般的业务对象之间,业务对象与持久层之间都存在这样或那样的依赖关系。那么,如何降低对象之间的依赖关系,IoC正式解决这个问题。
在传统的实现中,由程序内部的代码来控制对象之间的关系。当一个对象需要依赖另一个对象时,我们用new来创建它的依赖对象,实现两个组件的组合关系。这种实现方式会造成组件之间的耦合。控制反转是指应用程序中对象的创建、销毁等不再由程序本身编码实现,而是由外部的Spring容器来控制,所以称为控制反转。这种控制权的转移带来的好处是降低了对象简单间的依赖关系,即实现了解耦。
IoC的字面意思是控制反转,它包括两个内容:其一就是控制,其二就是反转。控制就选择被调用者类的控制权,反转指这种控制权从具体的调用者类中移除,转而交给一个装配者手中了。
在软件模式中具体表现为:某一个接口具体实现类的选择控制权从调用者类中移除,转交给第三方仲裁。第三方为配置文件,由IOC容器装载配置文件之后,自动映射生成对象及其属性。
IoC的具体方法是依赖注入DI(Dependency ):组件之间的依赖关系由容器在运行期间决定,形象的说,即由容器动态的将某种依赖关系注入到主键之中。
三、依赖注入DI的三种方式
1、构造函数注入
在构造器注入中,我们通过在调用者类的构造器中将被调用者对象变量赋值即可完成注入

public class Chairman { public void managerCourse(){ Teacher teacher=new Bill(); JavaTrad javatrad=new JavaTrad(teacher); //构造器注入 javatrad.javaCourse(); } public static void main(String[] args) { new Chairman().managerCourse(); } }


public class JavaTrad { private Teacher teacher; public JavaTrad(Teacher teacher){//构造函数注入方法 this.teacher=teacher; } public void javaCourse(){ this.teacher.teach("Spring IoC章节!"); } }

2、set属性注入方式
在set属性注入中,我们通过使用调用者的set方法将teacher的具体对象传入teacher中,即可完成注入。

<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <bean name="teacher" class="com.weikun.IoC6.Bill"></bean> <bean id="trad" class="com.weikun.IoC6.JavaTrad"> <property name="teacher" ref="teacher"></property> </bean> </beans>


public class JavaTrad{ private Teacher teacher; public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } public void JavaCourse(){ this.teacher.teach("Spring IoC章节!"); } }


public class Test { public static void main(String[] args) { Resource resource=new ClassPathResource("applicationContext1.xml");//容器 BeanFactory beanFactory=new XmlBeanFactory(resource); JavaTrad javaTrad=(JavaTrad)beanFactory.getBean("trad"); Teacher teacher=(Teacher)beanFactory.getBean("teacher"); javaTrad.getTeacher().teach("asd"); } }

3、接口注入方式
让调用者也实现一个接口,接口中定义一个接口注入方法,在具体调用者类中实现它,从而完成属性的注入(方法类似于自定义一个setter方法)

public class JavaTrad implements Trad{ private Teacher teacher; public void JavaCourse(){ this.teacher.teach("Spring IoC章节!"); } public void injectTeacher(Teacher teacher) {//接口属性注入方式 // TODO Auto-generated method stub this.teacher=teacher; } }

public interface Trad { void injectTeacher(Teacher teacher);}
4、四种依赖注入方式的对比
1)、接口注入
从注入方式的使用上来说,接口注入是不提倡的一种方式,极少被用户使用。因为它强制被注入对象实现容器的接口,带有“侵入性”,而构造方法注入和setter方法注入则不需要如此。
2)、setter注入
这种注入方式与传统的JavaBean写法很相似,程序员更容易理解和接受,通过setter方式设定依赖关系显得更加直观自然。
缺点是组件使用者或许会忘记组件注入需要的依赖关系,同时依赖可能会因为setter方法的调用而被修改。
3)、构造注入
这种方法的优点是:构造注入可以在构造器中决定依赖关系的注入顺序。依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明。
缺点:对于复杂的依赖关系如果采用构造注入,会导致构造器过于臃肿,难以阅读。
5、IoC的装载机制
1、IoC容器
Spring提供了强大的IoC容器来管理组成应用程序中的Bean,要利用容器提供的服务,就必须配置Bean,配置文件描述了Bean的定义和他们之间的依赖关系。Spring通过大量引入了Java的反射机制动态生成Bean对象并注入到程序中避免硬编码,实现了该功能的核心组件是BeanFactory,而ApplicationContext继承了BeanFactory接口,提供了更多的高级特性,建议优先使用后者。
ApplicationContext的实现类如下:
1)、ClassPathXmlApplicationContext:从CLASSPATH下加载文件
2)、FileSystemXmlApplicationContext:从文件系统中加载文件
首先,可以通过任一实现类来将配置文件中定义的Bean加载到容器中,如:(这里的ctx就是容器)
1)、ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
2)、ApplicationContext ctx=new FileSystemXmlApplicationContext("classpath:bean.xml");
然后,通过下列语句获取Bean的实例
Moveable animal=(Moveable) ctx.getBean("animal");
6、IoC的零配置注解写法
如果Bean不是自己编写的类(如SessionFactory),注解配置将无法实施,此时XML配置是唯一可以使用的方式
1)、@Autowired
它对类的成员变量、方法以及构造方法进行标注,完成自动装配的工作。

import org.springframework.beans.factory.annotation.Autowired; public class Animal{ Private MessagePriter printer; @Autowired public void setPrinter(MessagePriter printer){ this.priter=printer; } }


<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd "> <bean id="movePrinter" class="com.zxc.A.movePriter"></bean> <bean id="animal" class="com.zxc.A.JavaTrade"> <property name="animalType" value="Bird"/> <property name="moveMode" value="fly"/> </bean> </beans>

2)、@Qualifier
如果一个bean的属性可能来自多个其他的候选bean,导致Spring无法确定使用那一个bean,当Spring容器在启动时就会抛出BeanCreationException异常。Spring允许我们通过@Qualifie注解指定注入bean的名称。
import org.springframework.beans.factory.annotation.Autowired; public class Animal{ @Autowired Private @Qualifier(value="screen")MessagePriter printer; }
通常@Qualifer和@Autowired结合使用,且置于成员变量类型的前面。
3)、@Resource
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入的,而@Resource默认按byName自动注入罢了。
4)、@Component
虽然可以通过@Autowired或@Resource在Bean类中使用自动注入功能,但是还是需要在XML中定义<bean>。而通过注解的@Component就可以通过注解就定义Bean,在类前加上@Component
一、Hibernate完成一个事务的过程
背景:
当多个事务同时要同一个数据时,如果没有良好的控制手段,则有可能同一个数据被别的事务修改而造成混乱,此时,可以利用数据库底层提供的锁机制对当前操作的数据进行锁定,以防止其他事务同时操作事务。
二、悲观锁(Pessimistic Locking)
每次在操作数据时,总是悲观的认为会有别的事务也会操作同一数据,因此锁住该数据,直到自己操作完成后在解除锁。
优点:安全 缺点:性能稍差
可以使用Query或Criteria的setLockMode()方法来设定。
LockMode.UPGRADE:利用数据库的for update子句实现锁定
LockMode.UPGRADE_NOWWAIT:使用for update nowait子句进行锁定,oracle使用。
悲观锁使用:
使用Query类下的setLockMode()方法,第一个参数表示数据库名,第二个参数LockMode.UPGRADE_NOWWAIT表示强力锁止,表示任何时候只与允许一个线程操作
三、乐观锁(Optimistic Locking)
相对于悲观锁而言,它通常认为多个事务同时操作同一个数据的情况是很少的,因而不做数据库层次上的锁定,只是基于数据版本表示,实现应用程序级别上的锁定机制。
优点:性能稍差 缺点:安全
乐观锁使用:
为数据增加一个版本标识,一般是通过数据库表增加一个version字段来实现的。当读取数据时,版本号自动加一。在提交数据时将现有版本号与数据库表对应记录的版本号进行比对,如果提交的数据版本号大于数据库表中的版本号,则允许更新数据,否则禁止更新数据。
之后在po下的加乐观锁的那个类的对应version属性上加上@version注解
一、AOP简介
AOP是Aspect-Oriented Programming的缩写,即面向切面编程。利用oop思想,可以很好的处理业务流程,但是不能把系统中某些特定的重复性行为封装到模块中。例如,在很多业务中都需要记录操作日志,结果我们不得不在业务流程中嵌入大量的日志记录代码。无论是对业务代码还是对日志记录代码来说,维护都是相当复杂的。由于系统中嵌入了这种大量的与业务无关的其他重复性代码,系统的复杂性、代码的重复性增加了。维护起来会更加复杂。
AOP可以很好解决这个问题,AOP关注的是系统的“截面”,在适当的时候“拦截”程序的执行流程,把程序的预处理和后期处理交给某个拦截器来完成。比如,访问数据库时需要记录日志,如果使用AOP的编程思想,那么在处理业务流程时不必在去考虑记录日志,而是把它交给一个专门的例子记录模块去完成。这样,程序员就可以集中精力去处理业务流程,而不是在实现业务代码时嵌入日志记录代码,实现业务代码与非业务代码的分别维护。在AOP术语中,这称为关注点分离。AOP的常见应用有日志拦截、授权认证、数据库的事务拦截和数据审计等。
二、AOP优点
当一个方法,对不同的用户的功能要求不满足时,那么需要在此方法的地方就可以出现变化;在这个变化点进行封转,留下一个可扩展的接口,便于后期的维护;
三、AOP专业名词
(1)通知(增强)Advice
通知定义了切面是什么以及何时使用,应该应用在某个方法被调用之前?之后?还是抛出异常时?等等。
(2)连接点 Join point
连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时,抛出异常时,甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程中,并添加新的行为。
(3)切点 Pointcut
切点有助于缩小切面所通知的连接点的范围。如果说通知定义了切面的“什么”和“何时”的话,那么切点就定义了“何处”,切点会匹配通知所要织入的一个或多个连接点,一般常用正则表达式定义所匹配的类和方法名称来指定这些切点。
(4)切面 Aspect
切面是通知和切点的结合。通知和切点定义了切面的全部内容——它是什么,在何时何处完成其功能。
(5)引入 Introduction
引入允许我们向现有的类添加新方法或属性,从而无需修改这些现有类的情况下,让他们具有新的行为和状态。
(6)织入 Weaving
在过去我常常把织入与引入的概念混淆,我是这样来辨别的,“引入”我把它看做是一个定义,也就是一个名词,而“织入”我把它看做是一个动作,一个动词,也就是切面在指定的连接点被织入到目标对象中。
四、注解方式实现AOP
1、C包下在resources文件夹中创建application2.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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd "> <context:component-scan base-package="com.zxc.C"> <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> </context:component-scan> <aop:aspectj-autoproxy/> </beans>

<context:component-scan base-package="com.zxc.C">用来自动扫描com.zxc.C包中带有@component注解的bean类,然后将其加载到内存中。
<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> 这是aspect切面包的位置。
<aop:aspectj-autoproxy/>用来启用Spring对@Aspect切面配置的支持。
2、在java类下创建Chinese类,如下:
这个就是测试用的业务代码,@Componet代表这是个javabean,有xml配置后,自动扫描装载。

package com.zxc.C; import org.springframework.stereotype.Component; @Component public class Chinese{ public String say(String name){ //int a=1/0;用来测试异常增强的 System.out.println("主方法"); System.out.println(name); return "返回值"; } }

3、在java类下创建Test类,用来测试代码:

package com.zxc.C; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("application2.xml"); Chinese chinese=(Chinese)ctx.getBean("chinese"); chinese.say("环绕增强测试"); } }

Application用来生成IoC容器,装载application2.xml配置文件,之后通过getBean方法来反射创建一个chinese的对象,在调用其核心业务方法say,say的内容是随意写的。
4、在java类下创建切面类MyAspect类

package com.zxc.C; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; @Aspect public class MyAspect { @Before("execution(* com.zxc.C.*.say*(..))") public void ok(){ System.out.println("前置增强"); } @After("execution(* com.zxc.C.*.say*(..))") public void ok1(){ System.out.println("后置增强"); } @AfterReturning(pointcut = "execution(* com.zxc.C.*.say*(..))",returning ="myreturn" ) public void ok2(Object myreturn){ System.out.println(myreturn+"返回增强"); } // @AfterThrowing(pointcut ="execution(* com.zxc.C.*.say*(..))",throwing = "myerror") // public void ok3(Throwable myerror){ // System.out.println(myerror+"返回增强"); // } @Around("execution(* com.zxc.C.*.say*(..))") public void ok4(ProceedingJoinPoint pjp){ try { System.out.println("环绕点前"); Object[] objects=pjp.getArgs(); objects[0]=objects[0]+"环绕增强方法"; System.out.println(pjp.proceed(objects)); System.out.println("环绕点后"); } catch (Throwable throwable) { throwable.printStackTrace(); } } }

a、增强类型有:前置增强Before、后置增强After、环绕增强Around、异常后增强AfterThrowing、返回增强AfterReturning:用在关注点方法前
优先级:(可以加上@order(num)来标注优先级,数越小优先级越高,1最小)环绕前增强>前置增强>异常增强>返回增强>环绕后增强>后置增强
b、其中环绕增强需要在方法形参上加上形参:ProceedingJoinPoint pjp表示可在切面分钟执行的连接点,在关注点方法中,加入pjp.proceed()方法,可以运行业务方法。
而在异常增强中需要加上形参Throwable error,用来将业务代码中的错误传到关注点方法中。
c、切点的书写规则:(在异常后增强和返回增强中都要加上pointcut)
AspectJ切点指示器
d、在切面类上要记得加注解@Abstrct,表示这是个切面。
e、jointpoint中的几个常用方法
Sping框架的IOC特性 悲观锁、乐观锁 Spring的AOP特性的更多相关文章
- Java并发 行级锁/字段锁/表级锁 乐观锁/悲观锁 共享锁/排他锁 死锁
原文地址:https://my.oschina.net/oosc/blog/1620279 前言 锁是防止在两个事务操作同一个数据源(表或行)时交互破坏数据的一种机制. 数据库采用封锁技术保证并发操作 ...
- 最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁
在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 01.乐观锁 vs 悲观 ...
- Java最全锁剖析:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁
乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会 ...
- Hibernate悲观锁/乐观锁
如果需要保证数据访问的排它性,则需对目标数据加"锁",使其无法被其它程序修改 一,悲观锁 对数据被外界(包括本系统当前的其它事务和来自外部系统的事务处理)修改持保守态度,通过数据库 ...
- SQL Server 锁机制 悲观锁 乐观锁 实测解析
先引入一些概念,直接Copy其他Blogs中的,我就不单独写了. 一.为什么会有锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 1.丢失更新 A,B两个用户读同一数据并进行修改,其中 ...
- Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
Optimistic concurrency control https://en.wikipedia.org/wiki/Optimistic_concurrency_control Optimist ...
- Redis 事物、悲观、乐观锁 (详细)
1,概论 事物这东西相信大家都不陌生吧,在学习Spring,Mybatis等框架中, 只要是涉及到数据存储和修改的,都会有事物的存在, 废话就不多说了下面我们来简单的介绍下Redis事物以及锁. 2, ...
- 【MySQL】悲观锁&乐观锁
悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...
- innodb 悲观锁,乐观锁
转 http://www.cnblogs.com/chenwenbiao/archive/2012/06/06/2537508.html CREATE TABLE `products` ( `id` ...
随机推荐
- java组件不存在解决方案:右侧Maven Projects展开后左上角第一个刷新按钮 刷新后就会从新加载所有java的依赖项了
java组件不存在解决方案:右侧Maven Projects展开后左上角第一个刷新按钮 刷新后就会从新加载所有java的依赖项了 软件:idea 问题产生:其他同事进行开发,引入新java组件后提交 ...
- Zend Studio 离线汉化包下载方法
进入eclipse官网 语言包位置 http://www.eclipse.org/babel/downloads.php
- 卸载钩子 UnhookWindowsHookEx
The UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindow ...
- sqlite3接口简要说明
本文介绍一下SQLite C/C++接口. 早期的SQLite C/C++接口只有5个接口函数, 很容易学习. 新版本的SQLite新增了很多功能, 目前大概有185个API接口.本文介绍一些核心的A ...
- 「 Luogu P1122 」 最大子树和
# 题目大意 真讨厌题面写的老长老长的. 这个题的意思就是给定一棵无根树,每个节点都有一个美丽值(可能是负数),可以删掉一些边来删除某些点,现在要求你求出可以删掉任意条边的情况下,这个树上的剩余节点的 ...
- Dijkstra+set堆优化局部模板
这是某天2018-10-25写的某题(P1613-luogu)的局部代码,目的是方便自己记忆一些细节,所以这里不过多赘述算法原理或题目 邻接矩阵mapp表示有向图 struct ELE { int i ...
- Mybatis的一级二级缓存
Mybatis提供了缓存机制,可以减轻数据库的压力,提高性能 Mybatis的缓存分为两级:一个是一级缓存,一个二级缓存 一级缓存:即默认使用的缓存SqlSession级别的缓存,只在sqlsessi ...
- Windows——bat中的路径和工具栏运行bat的坑
工具栏添加的批处理环境 编写一个简单的批处理文件 set testEnv = %cd% pause 这里第一句:设置当前文件夹路径为环境变量testEnv的值 这里第二句:暂停命令窗口 第一次我们直接 ...
- Linux命令整理(2018/9/9-2018/9/15)
根据本周的Linux学习进度,整理了部分Linux知识及常用命令,待完善…… 1.显示默认启动方式(默认启动目标): systemctl get-default 2.设置默认启动方式(默认启动目标): ...
- Altium designer中生成gerbera文件
在Altium designer中生成gerbera文件的方法有很多,不同版本,差异行不太大,正如下边链接地址里博主在10版本下的方法,在6.0版本长也是这样 http://blog.sina.com ...