1.spring依赖注入的原理
链接:https://www.cnblogs.com/mthoutai/p/7278427.html
假设我们去看Spring的源代码可能涉及的类和接口相当多,不易掌握。在此我用自己的代码和方式来帮助我们Spring依赖注入的过程。
当我们启动Spring容器的时候他会运行以下几个过程:
(1、载入Xml配置文件(readXML(String filename))在Spring这个由ApplicationContext类完毕
这一步会解析Xml属性。把bean的属性存放到BeanDefinition类中
代码例如以下:
1 /** 2 * 读取xml配置文件 3 * @param filename 4 */ 5 private void readXML(String filename) { 6 SAXReader saxReader = new SAXReader(); 7 Document document=null; 8 try{ 9 URL xmlpath = this.getClass().getClassLoader().getResource(filename); 10 document = saxReader.read(xmlpath); 11 Map<String,String> nsMap = new HashMap<String,String>(); 12 nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间 13 XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径 14 xsub.setNamespaceURIs(nsMap);//设置命名空间 15 List<Element> beans = xsub.selectNodes(document);//获取文档下全部bean节点 16 for(Element element: beans){ 17 String id = element.attributeValue("id");//获取id属性值 18 String clazz = element.attributeValue("class"); //获取class属性值 19 BeanDefinition beanDefine = new BeanDefinition(id, clazz); 20 XPath propertysub = element.createXPath("ns:property"); 21 propertysub.setNamespaceURIs(nsMap);//设置命名空间 22 List<Element> propertys = propertysub.selectNodes(element); 23 for(Element property : propertys){ 24 String propertyName = property.attributeValue("name"); 25 String propertyref = property.attributeValue("ref"); 26 PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref); 27 beanDefine.getPropertys().add(propertyDefinition); 28 } 29 beanDefines.add(beanDefine); 30 } 31 }catch(Exception e){ 32 e.printStackTrace(); 33 } 34 }
(2、Bean的实例化
在配置文件以bean的id为key。BeanDefinition为value放到Map中
1 /** 2 * 完毕bean的实例化 3 */ 4 private void instanceBeans() { 5 for(BeanDefinition beanDefinition : beanDefines){ 6 try { 7 if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())) 8 sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance()); 9 } catch (Exception e) { 10 e.printStackTrace(); 11 } 12 } 13 14 }
(3、为Bean的输入注入值。完毕依赖注入
1 /** 2 * 为bean对象的属性注入值 3 */ 4 private void injectObject() { 5 for(BeanDefinition beanDefinition : beanDefines){ 6 Object bean = sigletons.get(beanDefinition.getId()); 7 if(bean!=null){ 8 try { 9 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); 10 for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){ 11 for(PropertyDescriptor properdesc : ps){ 12 if(propertyDefinition.getName().equals(properdesc.getName())){ 13 Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private 14 if(setter!=null){ 15 Object value = sigletons.get(propertyDefinition.getRef()); 16 setter.setAccessible(true); 17 setter.invoke(bean, value);//把引用对象注入到属性 18 } 19 break; 20 } 21 } 22 } 23 } catch (Exception e) { 24 } 25 } 26 } 27 }
事实上Spring依赖注入的过程就是这么简单,再就是各种细节了。比方懒载入、单例等的额外处理了。
2.linux脚本
之前写过bash shell脚本 。略。
3.集群搭建
一般都是下载相关的包,解压,部署依赖环境,配置环境变量。略
4.常用spring注解
@Component
作用: 用于把当前类对象存入spring容器中
属性: value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写
1 @Component 2 public class AccountDaoImpl implements IAccountDao { 3 public void saveAccount() { 4 System.out.println("保存了账户1111111111111"); 5 } 6 }
在bean.xml中配置
<context:component-scan base-package="com.itheima"></context:component-scan>
测试代码
1 public static void main(String[] args) { 2 ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); 3 IAccountDao dao = ac.getBean("accountDaoImpl",IAccountDao.class); 4 System.out.println(dao); 5 dao.saveAccount(); 6 ac.close(); 7 }
由Component衍生而来的注解:
Controller:一般用在表现层
Service: 一般用在业务层
Repository:一般用在持久层
@Autowired
按照类型注入,有多个接口的实现会报错
自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错;
如果Ioc容器中有多个类型匹配时:先按照类型匹配,如果找到多个类型bean对象,再按照变量名作为bean的id去匹配,如果id不匹配,报错
Autowired出现位置: 可以是变量上,也可以是方法上
细节:在使用注解注入时,set方法就不是必须的了。
@Qualifier
用于注入数据的注解
但是在给方法参数注入时可以的
属性:value:用于指定注入bean的id
@Resource
作用:直接按照bean的id注入。它可以独立使用
属性:name:用于指定bean的id
注意: @Resource`是由JDK提供的注解,在JDK1.9之后移除到扩展模块之中.
所以如果想使用`@Resource`注解注入数据,请使用1.8及以下版本JDK
@Value
作用:用于注入基本类型和String类型的数据
属性:value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)SpEL的写法:${表达式}
@Scope
指定bean的作用范围。
属性:
value:指定范围的值。 取值:`singleton` `prototype` `request` `session` `globalsession`
5.数据库创建索引
链接:https://blog.csdn.net/tomorrow_fine/article/details/78337735
1 --创建一个普通索引 2 create table index1 ( 3 id int, 4 name VARCHAR(20), 5 sex boolean, 6 INDEX(id) 7 8 ); 9 --查看索引是否被使用 10 EXPLAIN SELECT * from index1 where id =1 ; 11 12 --创建一个唯一性索引 13 create table index2( 14 id int unique, 15 name varchar(20), 16 unique index index2_id(id ASC) 17 ); 18 --查看表结构 19 SHOW CREATE table index2 20 21 --创建全文索引 22 create table index3( 23 id int, 24 info varchar(20), 25 FULLTEXT index index3_info(info) 26 27 )ENGINE=MyISAM; 28 29 SHOW CREATE table index3; 30 31 --创建单列索引 32 CREATE TABLE index4( 33 id INT, 34 subject VARCHAR(30), 35 INDEX index4_st(subject(10)) 36 ); 37 show create table index4; 38 39 --创建多列索引 40 CREATE TABLE index5(id INT, 41 name VARCHAR(20), 42 sex CHAR(4), 43 INDEX index5_ns(name,sex) 44 45 ); 46 47 --创建空间索引 48 CREATE TABLE index6(id INT, 49 space GEOMETRY NOT NULL, 50 SPATIAL INDEX index6_sp(space) 51 )ENGINE=MyISAM;
6.创建视图
链接:http://www.w3school.com.cn/sql/sql_view.asp
创建视图语法:
1 CREATE VIEW view_name AS 2 SELECT column_name(s) 3 FROM table_name 4 WHERE condition
在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。
视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。
注释:数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。
注释:视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。
7. 抽象类和接口的区别?
链接:https://www.cnblogs.com/yongjiapei/p/5494894.html
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
7、抽象类里可以没有抽象方法
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。