joomla 网站模版,用vue.js做网站,电子商务以后可以做什么工作,1122t完整项目结构
├── pom.xml
└── src/├── main/│ ├── java/│ │ └── com/│ │ └── zhang/│ │ ├── bean/│ │ │ ├── Address.java│ │ │ ├── MyBeanPostProcessor.java│ │ …完整项目结构
├── pom.xml
└── src/├── main/│ ├── java/│ │ └── com/│ │ └── zhang/│ │ ├── bean/│ │ │ ├── Address.java│ │ │ ├── MyBeanPostProcessor.java│ │ │ └── Person.java│ │ └── factory/│ │ ├── MyFactoryBean.java│ │ ├── PersonInstanceFactory.java│ │ └── PersonStaticFactory.java│ └── resources/│ │ ├── db.properties│ └── ioc.xml└── test/└── java/└── MyTest.java项目主要内容和学习方面
这个项目是一个Spring框架的学习练习demo主要学习了以下几个方面Spring IoC容器基础
通过ClassPathXmlApplicationContext加载配置文件并创建IoC容器学习了从容器中获取Bean的多种方式根据id、根据类型Bean的作用域
测试了Spring中Bean的单例模式依赖注入
通过配置文件实现Person和Address等实体类的依赖注入Bean的生命周期
实现了MyBeanPostProcessor类学习Bean的后置处理器机制工厂模式
学习了多种工厂创建Bean的方式
静态工厂PersonStaticFactory实例工厂PersonInstanceFactoryFactoryBeanMyFactoryBean数据源配置
项目中包含了Druid数据源的配置测试主要Java类说明
实体类Person.java人员实体、Address.java地址实体后置处理器MyBeanPostProcessor.javaBean生命周期处理器工厂类PersonStaticFactory.java静态工厂、PersonInstanceFactory.java实例工厂、MyFactoryBean.javaFactoryBean实现测试类MyTest.java用于测试Spring的各种功能
项目依赖包括Spring框架的核心模块、MySQL驱动和Druid数据源。
代码
beanpublic class Address {private String province;private String city;private String town;public Address() {System.out.println(Address被创建);}public String getProvince() {return province;}public void setProvince(String province) {this.province province;}public String getCity() {return city;}public void setCity(String city) {this.city city;}public String getTown() {return town;}public void setTown(String town) {this.town town;}Overridepublic String toString() {return Address{ province province \ , city city \ , town town \ };}
}import java.util.*;public class Person {private Integer id;private String name;private Integer age;private String gender;
// private Date date;private String[] hobbies;private Address address;private ListAddress lists;
private SetString sets;
private MapString,Object maps;
private Properties properties;public void init(){
// 先写n行代码完成初始化功能System.out.println(person对象初始化完成);
}
public void destroy(){System.out.println(person对象被销毁);
}public Person() {System.out.println(person被创建);}public Person(Address address) {this.address address;}public Person(Integer id, String name, Address address) {this.id id;this.name name;this.address address;}// public Person(Integer id, String name, Integer age, String gender, Date date) {
// this.id id;
// this.name name;
// this.age age;
// this.gender gender;
// this.date date;
// }public Person(Integer id, String name, Integer age, String gender) {this.id id;this.name name;this.age age;this.gender gender;}public Person(Integer id, String name, String gender) {this.id id;this.name name;this.gender gender;System.out.println(gender... ...);}public Person(Integer id, String name, Integer age) {this.id id;this.name name;this.age age;System.out.println(age... ...);}public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender gender;}public String[] getHobbies() {return hobbies;}public void setHobbies(String[] hobbies) {this.hobbies hobbies;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address address;}public ListAddress getLists() {return lists;}public void setLists(ListAddress lists) {this.lists lists;}public SetString getSets() {return sets;}public void setSets(SetString sets) {this.sets sets;}public MapString, Object getMaps() {return maps;}public void setMaps(MapString, Object maps) {this.maps maps;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties properties;}
// public Date getDate() {
// return date;
// }
//
// public void setDate(Date date) {
// this.date date;
// }Overridepublic String toString() {return Person{ id id , name name \ , age age , gender gender \ , hobbies Arrays.toString(hobbies) , address address , lists lists , sets sets , maps maps , properties properties };}}
初始化的时候做事情
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanPostProcessor implements BeanPostProcessor {
// 在每一个对象的初始化方法之前执行public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println(postProcessBeforeInitialization:beanName);return bean;}/*** 在每一个对象的初始化方法之后执行* param bean 表示创建的具体对象* param beanName 表示bean的id属性* return* throws BeansException*/public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof Person){System.out.println();}else {System.out.println();}System.out.println(postProcessAfterInitialization:beanName);return bean;}
}
工厂
单例模式import com.zhang.bean.Person;
import org.springframework.beans.factory.FactoryBean;
/*此方式是spring创建bean方式的一种补充,用户可以按照需求创建对象,
* 创建的对象交由spring IOC容器来进行管理,无论是否是单例,都是在
* 用到的时候才会创建该对象,不用该对象不会创建*/
public class MyFactoryBean implements FactoryBeanPerson {/*返回获取的bean*/public Person getObject() throws Exception {Person personnew Person();person.setId(3);person.setName(王五);return person;}
/*获取返回bean的类型*/public Class? getObjectType() {return Person.class;}
/*判断当前bean是否是单例的*/public boolean isSingleton() {return true;}
}import com.zhang.bean.Person;
//*实例工厂类*/
public class PersonInstanceFactory {public Person getInstance(String name){Person person new Person();person.setId(2);person.setName(name);person.setAge(22);return person;}}import com.zhang.bean.Person;
/*静态工厂类*/
public class PersonStaticFactory {public static Person getInstance(String name){Person person new Person();person.setId(1);person.setName(name);person.setAge(11);return person;}
}
测试
import com.alibaba.druid.pool.DruidDataSource;
import com.zhang.bean.Address;
import com.zhang.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(ioc.xml);/*根据bean标签的id来获取对象*/
// Person person context.getBean(person, Person.class);
// Person person1 context.getBean(person, Person.class);
// System.out.println(personperson1);
// System.out.println(person);/*根据bean的类型来获取对象* 注意:当通过类型进行获取的时候如果存在两个相同类型对象将无法完成获取工作* */
// Person bean context.getBean(Person.class);
// System.out.println(bean);/*当需要从容器中获取对象的时候最好要保留无参构造方法因为底层的实现是反射*Object obj clazz.newInstance() ;默认调用无参的构造方法此方法已经被弃用Object obj clazz.newConstructorInstance();*/
// Person bean context.getBean(person6,Person.class);
// System.out.println(bean);
// Address address2 context.getBean(address2, Address.class);
// System.out.println(address2);
// Person son context.getBean(son,Person.class);
// System.out.println(son);
// Person parent context.getBean(parent,Person.class);
// System.out.println(parent);
// Person person2 context.getBean(person2, Person.class);
// Person person3 context.getBean(person2, Person.class);
// System.out.println(person2person3);
// Person person context.getBean(person, Person.class);
// System.out.println(person);
// Person person2 context.getBean(person2, Person.class);
// System.out.println(person2);
// Person myFactoryBean context.getBean(myFactoryBean, Person.class);
// System.out.println(myFactoryBean);Person person context.getBean(person2, Person.class);System.out.println(person);
// 关闭ioc容器
// ((ClassPathXmlApplicationContext) context).close();
// DruidDataSource dataSource context.getBean(dataSource2, DruidDataSource.class);
// System.out.println(dataSource);
// System.out.println(dataSource.getCloseCount());}
}
配置文件
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxmlns:conthttp://www.springframework.org/schema/contextxmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd!--7到149一起注释掉--!-- lt;!ndash;在进行框架配置的时候可以使用xml文件也可以使用注解的方式--!-- 很多同学觉得xml的方式比较麻烦但是xml的配置方式还是要学习的因为在项目开发过程中,--!-- 很多情况下是xml和注解一起工作而且xml配置的方式比较完整ndash;gt;--!-- lt;!ndash;bean idperson classcom.zhang.bean.Person scopeprototypendash;gt;--!-- lt;!ndash; scopeprototype改为分单例ndash;gt;--!-- bean idperson classcom.zhang.bean.Person--!-- lt;!ndash;根据属性值设置的时候name的名称取决于set方法后面的参数首字符小写的名称ndash;gt;--!-- property nameid value1/property--!-- property namename valuezhangsan/property--!-- property nameage value20/property--!-- property namegender value男/property--!-- lt;!ndash; property namedate refnow/propertyndash;gt;--!-- lt;!ndash; property namedate value2020/02/06/propertyndash;gt;--!-- /bean--!-- bean idnow classjava.util.Date--!-- /bean--!-- lt;!ndash;使用构造器方法赋值的时候参数的name属性是由什么来决定的?由构造方法的参数名称决定的--!-- name:表示参数列表的名称--!-- value:表示实际的具体值--!-- type:表示值的类型--!-- index:表示值的下标从0开始--!-- ndash;gt;--!-- bean idperson2 classcom.zhang.bean.Person--!-- constructor-arg nameid value2/constructor-arg--!-- constructor-arg namename valuelisi/constructor-arg--!-- constructor-arg nameage value20/constructor-arg--!-- constructor-arg namegender value男/constructor-arg--!-- /bean--!-- lt;!ndash;当通过构造器方法赋值的时候可以把name属性省略不写但是要注意必须要保证参数值跟构造器的参数列表的顺序一致,--!-- 如果非要不一致的话可以通过index的下标方式来标注从0开始 ndash;gt;--!-- bean idperson3 classcom.zhang.bean.Person--!-- constructor-arg value2 index2/constructor-arg--!-- constructor-arg valuelisi/constructor-arg--!-- constructor-arg value22 index0/constructor-arg--!-- constructor-arg value男/constructor-arg--!-- /bean--!-- lt;!ndash;当有多个相同参数的构造方法存在的时候默认情况下是覆盖的过程后面的构造方法会覆盖前面的构造方法,--!-- 如果非要赋值给另外一个构造方法的话可以使用type的参数来进行指定ndash;gt;--!-- bean idperson4 classcom.zhang.bean.Person--!-- constructor-arg value4/constructor-arg--!-- constructor-arg valuewangwu/constructor-arg--!-- constructor-arg value22 typejava.lang.Integer/constructor-arg--!-- /bean--!-- lt;!ndash;总结:--!-- 在日常工作中一般都是用name, value的方式很少有人去使用index或者type的方式但是要注意各种情况出现的问题--!-- ndash;gt;--!-- lt;!ndash; 使用p命名空间来给属性命名--!-- ndash;gt;--!-- bean idperson5 classcom.zhang.bean.Person p:id5 p:namezhaoliu p:age25 p:gender女/bean--!-- lt;!ndash; 给复杂类型进行赋值ndash;gt;--!-- bean idperson6 classcom.zhang.bean.Person--!-- property nameid value6/property--!-- property namename valuezhangsan6/property--!-- property nameage value20/property--!-- property namegender value男/property--!-- lt;!ndash; 给数组赋值 使用array标签ndash;gt;--!-- lt;!ndash; property namehobbies valuebook,girl,movie/propertyndash;gt;--!-- property namehobbies--!-- array--!-- valuebook/value--!-- valuegirl/value--!-- valuemovie/value--!-- /array--!-- /property--!-- lt;!ndash; 引用类型赋值可以使用ref引入外部beanndash;gt;--!-- property nameaddress refaddress/property--!-- lt;!ndash; 给list 赋值ndash;gt;--!-- lt;!ndash; property namelists value1,2,3/propertyndash;gt;--!-- property namelists--!-- list--!-- lt;!ndash;使用内部bean,无法从IOC容器中直接获取对象的值ndash;gt;--!-- bean idaddress2 classcom.zhang.bean.Address--!-- property nameprovince value北京/property--!-- /bean--!-- bean classcom.zhang.bean.Address--!-- property nameprovince value上海/property--!-- /bean--!-- lt;!ndash;使用外部bean可以随意从IOC容器获取对象的值ndash;gt;--!-- ref beanaddress/ref--!-- /list--!-- /property--!-- property namesets--!-- set--!-- valuezhangsan/value--!-- valuezhangsan/value--!-- valuewangwu/value--!-- /set--!-- /property--!-- property namemaps--!-- map--!-- entry keya valueaaa/entry--!-- entry keyaddress value-refaddress/entry--!-- entry keyaddress2--!-- bean classcom.zhang.bean.Address--!-- property nameprovince value广东/property--!-- /bean--!-- /entry--!-- entry--!-- key--!-- valuehehe/value--!-- /key--!-- valuehaha/value--!-- /entry--!-- entry keylist--!-- list--!-- value11/value--!-- value22/value--!-- /list--!-- /entry--!-- /map--!-- /property--!-- property nameproperties--!-- props --!-- prop key111aaa/prop--!-- prop key222bbb/prop--!-- /props--!-- /property--!-- /bean--!-- bean idaddress classcom.zhang.bean.Address--!-- property nameprovince value河北省/property--!-- property namecity value邯郸/property--!-- property nametown value武安/property--!-- /bean--!--lt;!ndash;bean之间的继承关系ndash;gt;--!--lt;!ndash; 可以使用abstract标签定义抽象bean无法进行实例化ndash;gt;--!-- bean idparent classcom.zhang.bean.Person abstractfalse--!-- lt;!ndash;根据属性值设置的时候name的名称取决于set方法后面的参数首字符小写的名称ndash;gt;--!-- property nameid value1/property--!-- property namename valuezhangsan/property--!-- property nameage value20/property--!-- property namegender value男/property--!-- /bean--!--lt;!ndash; 可以通过parent属性来获取父bean中的某些属性值ndash;gt;--!--bean idson classcom.zhang.bean.Person parentparent--!-- property namename valuehaha/property--!--/bean--!-- 创建bean的时候依赖关系当bean对象被创建的时候是按照xml配置文件定义的顺序创建的谁在前谁就先被创建如果需要干扰创建的顺序可以使用 depends-on属性一般在实际工作中不必在意bean创建的顺序无论依赖的对象在创建完成之后都会进行赋值操作--!-- bean idperson classcom.zhang.bean.Person depends-onaddress /bean--!-- bean idaddress classcom.zhang.bean.Address /bean--!-- 设置bean对象的生命周期通过scope属性可以指定当前bean的作用域singleton:单例模式、从ioc容器中获取的都是同一个对象默认的作用域prototype多例模式、从IOC容器中获取的对象每次都是新创建的在spring4.x的版本中还包括另外两个作用域request每次发送请求都会有一个新的对象session每次会话都会由一个新的对象几乎不用从来没有用过因此在5版本的时候就被淘汰了--!-- 注意如果是单例作用域的话每次在创建ioc容器完成之前此对象就已经创建完成如果是prototype作用域的话每次是在需要用到此对象的时候才会创建--!-- bean idperson2 classcom.zhang.bean.Person scopesingleton/bean--!--利用工厂方式创建bean--!--静态工厂类名.静态方法()--!-- bean idperson classcom.zhang.factory.PersonStaticFactory factory-methodgetInstance--!-- constructor-arg valuezhangsan/constructor-arg--!-- /bean--!--实例工厂:先创建工厂实例,然后调用工厂实例的方法factory-bean:表示具体工程类的实例factory-method:表示具体工厂实例方法--!-- bean idinstanceFactory classcom.zhang.factory.PersonInstanceFactory/bean--!-- bean idperson2 classcom.zhang.bean.Person factory-beaninstanceFactory factory-methodgetInstance--!-- constructor-arg valuelisi/constructor-arg--!-- /bean--!-- bean idmyFactoryBean classcom.zhang.factory.MyFactoryBean/bean--!-- spring容器在创建对象的时候可以指定具体的初始化和销毁方法init-method:在对象创建完成之后会调用初始化方法destroy-method:在容器关闭的时候会调用销毁方法--!-- 初始化和销毁的方法跟scope属性也是相关联的如果是singleton的话初始化和销毁的方法都存在如果是prototype的话初始化会调用但是销毁的方法不会调用--!-- bean idperson classcom.zhang.bean.Person init-methodinit destroy-methoddestroy/bean--!-- bean idmyBeanPostProcessor classcom.zhang.bean.MyBeanPostProcessor/bean--!-- bean idaddress classcom.zhang.bean.Address/bean--!-- lt;!ndash;spring管理第三方beanndash;gt;--
!-- bean iddataSource classcom.alibaba.druid.pool.DruidDataSource--
!-- property nameusername valueroot/property--
!-- property namepassword value1234/property--
!-- property nameurl valuejdbc:mysql://localhost:3306/exam/property--
!-- property namedriverClassName valuecom.mysql.jdbc.Driver/property--
!-- /bean--
!-- lt;!ndash; 当需要引入外部的配置文件的时候需要导入一些context的命名空间ndash;gt;--!-- context:property-placeholder locationclasspath:db.properties/context:property-placeholder--
!-- lt;!ndash;在配置文件编写属性的时候需要注意--
!-- spring容器在进行启动的时候会读取当前系统的某些环境变量的配置--
!-- 当前系统的用户名是用username来表示的所以最好的方式是添加前缀来做区分ndash;gt;--
!-- bean iddataSource2 classcom.alibaba.druid.pool.DruidDataSource--
!-- property nameusername value${jdbc.username}/property--
!-- property namepassword value${jdbc.password}/property--
!-- property nameurl value${url}/property--
!-- property namedriverClassName value${driverClassName}/property--
!-- /bean--
!-- bean idperson classcom.zhang.bean.Person--
!-- property namename value${jdbc.username}/property--
!-- /bean--
!-- spring中的自动装配--bean idaddress classcom.zhang.bean.Addressproperty nameprovince value河北/propertyproperty namecity value邯郸/propertyproperty nametown value武汉/property/bean
!-- bean idaddress2 classcom.zhang.bean.Address--
!-- property nameprovince value河北2/property--
!-- property namecity value邯郸2/property--
!-- property nametown value武汉2/property--
!-- /bean--
!-- 在spring中可以使用自动装配的功能spring会把某些bean注入到另外的bean中
可以使用autowire属性来实现自动装配有一下几种情况
default/no:不装配
byName:按照id进行装配,根据set方法的后面的名称首字母小写决定的不是参数列表的名称
byType:按照bean的类型来进行装配但是如果有多个类型就会报错不知道选择哪一个具体的类型
constructor:按照构造器进行装配首先按照类型进行判断如果有多个类型相同的bean再按照id进行判断
--!-- 为什么使用bytype的时候会加载环境变量出来
环境变量中存储的就是keyvalve会放到那里面换一种类型就不会了
--!-- bean idperson classcom.zhang.bean.Person autowireconstructor/bean--
!-- SpEL表达式语言的使用--bean idperson2 classcom.zhang.bean.Person
!--可以引入bean对象的属性--
property namename value#{address.province}/property
!--可以支持运算符的所有操作--property nameage value#{2*3}/property
!--可以使用外部bean--property nameaddress value#{address}/property
!-- 可以调用静态方法--
property namehobbies value#{T(java.util.UUID).randomUUID().toString().substring(0,4)}/property
!--调用非静态方法--property namegender value#{address.getCity()}/property/bean
/beans
properties
jdbc.usernameroot
jdbc.password1234
urljdbc:mysql://localhost:3306/test
driverClassNamecom.mysql.jdbc.Driverpom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.zhang/groupIdartifactIdspring_study02/artifactIdversion1.0-SNAPSHOT/versiondependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.5/version/dependency!-- https://mvnrepository.com/artifact/com.alibaba/druid --dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.6/version/dependency!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.48/version/dependency/dependencies
/project