spring学习笔记pxlsdz

Spring:春天--->给软件行业带来了春天

2002年,RodJahnson首次推出了Spring框架雏形interface21框架。

2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。

很难想象RodJohnson的学历,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。

Spring理念:使现有技术更加实用.本身就是一个大杂烩,整合现有的框架技术

Spring是一个开源免费的框架,容器.

Spring是一个轻量级的框架,非侵入式的.

控制反转IoC,面向切面Aop

对事物的支持,对框架的支持

一句话概括:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。

Spring框架是一个分层架构,由7个定义良好的模块组成。Spring模块构建在核心容器之上,核心容器定义了创建、配置和管理bean的方式.

组成Spring框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

SpringBoot与SpringCloud

新建一个空白的maven项目

我们先用我们原来的方式写一段代码.

先写一个UserDao接口

publicinterfaceUserDao{publicvoidgetUser();}再去写Dao的实现类

publicclassUserDaoImplimplementsUserDao{ @Override publicvoidgetUser(){ System.out.println("获取用户数据"); }}然后去写UserService的业务接口

publicinterfaceUserService{ publicvoidgetUser();}最后写Service的实现类

publicclassUserServiceImplimplementsUserService{ privateUserDaouserDao=newUserDaoImpl(); @Override publicvoidgetUser(){ userDao.getUser(); }}测试一下

@Testpublicvoidtest(){//用户实际调用的是业务层,dao层他们不需要按触! UserServiceservice=newUserServiceImpl(); service.getUser();}这是我们原来的方式,开始大家也都是这么去写的对吧.那我们现在修改一下.把Userdao的实现类增加一个.

publicclassUserDaoMySqlImplimplementsUserDao{@OverridepublicvoidgetUser(){System.out.println("MySql获取用户数据");}}紧接着我们要去使用MySql的话,我们就需要去service实现类里面修改对应的实现

publicclassUserServiceImplimplementsUserService{privateUserDaouserDao=newUserDaoMySqlImpl();//这里@OverridepublicvoidgetUser(){userDao.getUser();}}在假设,我们再增加一个Userdao的实现类.

publicclassUserDaoOracleImplimplementsUserDao{@OverridepublicvoidgetUser(){System.out.println("Oracle获取用户数据");}}那么我们要使用Oracle,又需要去service实现类里面修改对应的实现。假设我们的这种需求非常大,这种方式就根本不适用了,甚至反人类对吧,每次变动,都需要修改大量代码。这种设计的耦合性太高了,牵一发而动全身。

那我们如何去解决呢

我们可以在需要用到他的地方,不去实现它,而是留出一个接口,利用set,我们去代码里修改下。

publicclassUserServiceImplimplementsUserService{privateUserDaouserDao;//利用set函数进行动态值实现注入publicvoidsetUserDao(UserDaouserDao){this.userDao=userDao;}@OverridepublicvoidgetUser(){userDao.getUser();}}现在去我们的测试类里,进行测试;

@Testpublicvoidtest(){UserServiceImplservice=newUserServiceImpl();service.setUserDao(newUserDaoMySqlImpl());service.getUser();//那我们现在又想用Oracle去实现呢service.setUserDao(newUserDaoOracleImpl());service.getUser();}已经发生了根本性的变化,很多地方都不一样了。以前所有东西都是由程序去进行控制创建,而现在是由我们自行控制创建对象,把主动权交给了调用者.程序不用去管怎么创建,怎么实现了。它只负责提供一个接口。

控制反转IoC(InversionofControl),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(DependencyInjection,DI)。

、导入Jar包

注:spring需要导入commons-logging进行日志记录.我们利用maven,它会自动下载对应的依赖项。

导入spring的jar包

publicclassHello{privateStringname;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicvoidshow(){System.out.println("Hello,"+name);}}编写我们的spring文件,这里我们命名为beans.xml

@Testpublicvoidtest(){//解析beans.xml文件,生成管理相应的Bean对象//获取Spring的上下文对象ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml");//getBean:参数即为spring配置文件中bean的id。//我们的对象都在spring管理了,我们要使用,直接去里面取出来就可以Hellohello=(Hello)context.getBean("hello");hello.show();}思考Hello对象是谁创建的【hello对象是由Spring创建的】

Hello对象的属性是怎么设置的【hello对象的属性是由Spring容器设置的】这个过程就叫控制反转:

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的

反转:程序本身不创建对象,而变成被动的接收对象.

依赖注入:就是利用set方法来进行注入的.

IOC是一种编程思想,由主动的编程变成被动的接收

可以通过newClassPathXmlApplicationContext去浏览一下底层源码.

我们在案例一中,新增一个Spring配置文件beans.xml

@Testpublicvoidtest2(){//获取ApplicationContext;拿到Spring的容器ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml");UserServiceImplserviceImpl=(UserServiceImpl)context.getBean("ServiceImpl");serviceImpl.getUser();}OK,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IoC,一句话搞定:对象由Spring来创建,管理,装配!

User.java

publicclassUser{privateStringname;publicUser(){System.out.println("user的无参构造函数");}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicvoidshow(){System.out.println("User{name="+name+"}");}}beans.xml

测试类

@Testpublicvoidtest3(){ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml");Useruser=(User)context.getBean("User");System.out.println(user);}结果可以发现,在调用show方法之前,User对象已经通过无参构造初始化了!

publicclassUser{privateStringname;publicUser(){System.out.println("user的无参构造函数");}publicUser(Stringname){this.name=name;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicvoidshow(){System.out.println("User{name="+name+"}");}}beans.xml有三种方式编写

测试

@Testpublicvoidtest4(){ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml");Useruser=(User)context.getBean("user");user.show();}结论:在配置文件加载的时候。其中管理的对象(所有bean)都已经初始化了!

别名

alias设置别名,为bean设置别名,可以设置多个别名

import

团队的合作通过import来实现,相当于合并到导入的文件

可以将多个配置文件,导入合并为一个。假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的。

applicationContext.xml

6、依赖注入(DI)依赖注入(DependencyInjection,DI)。

依赖:指Bean对象的创建依赖于容器.Bean对象的依赖资源.

注入:指Bean对象所依赖的资源,由容器来设置和装配.

在之前的案例已经详细讲过了

要求被注入的属性,必须有set方法,set方法的方法名由set+属性首字母大写,如果属性是boolean类型,没有set方法,是is.

测试pojo类:

Address.java

publicclassAddress{privateStringaddress;publicStringgetAddress(){returnaddress;}publicvoidsetAddress(Stringaddress){this.address=address;}}Student.java

测试:

@Testpublicvoidtest01(){ApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");Studentstudent=(Student)context.getBean("student");System.out.println(student.getName());}Bean注入注意点:这里的值是一个引用,ref

3、数组注入

西游记红楼梦水浒传4、List注入

听歌看电影爬山5、Map注入

6、set注入

LOLBOBCOC7、Null注入

8、Properties注入

20190604小明测试结果:

p命名和c命名注入

User.java:【注意:这里没有有参构造器!】

publicclassUser{privateStringname;privateintage;publicvoidsetName(Stringname){this.name=name;}publicvoidsetAge(intage){this.age=age;}@OverridepublicStringtoString(){return"User{"+"name='"+name+'\''+",age="+age+'}';}}1、P命名空间注入:需要在头文件中加入约束文件

解决:把有参构造器加上,这里也能知道,c就是所谓的构造器注入!为了防止p命名注入错误,也需要把无参构造加上。

测试代码:

@Testpublicvoidtest02(){ApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");Useruser=(User)context.getBean("user");System.out.println(user);}Bean的作用域在Spring中,那些组成应用程序的主体及由SpringIoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象.

几种作用域中,request、session作用域仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架),只能用在基于web的SpringApplicationContext环境。

单例模式(Spring默认机制)

当一个bean的作用域为Singleton,那么SpringIoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton作用域是Spring中的缺省作用域。要在XML中将bean定义成singleton,可以这样配置:

测试:

@Testpublicvoidtest03(){ApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");Useruser=(User)context.getBean("user");Useruser2=(User)context.getBean("user");System.out.println(user==user2);}Prototype原型模式:每次从容器中get的时候,都会产生一个新对象

当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。在XML中将bean定义成prototype,可以这样配置:

或者Request当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的SpringApplicationContext情形下有效。考虑下面bean定义:

针对每次HTTP请求,Spring容器会根据loginActionbean的定义创建一个全新的LoginActionbean实例,且该loginActionbean实例仅在当前HTTPrequest内有效,因此可以根据需要放心的更改所建实例的内部状态,而其他请求中根据loginActionbean定义创建的实例,将不会看到这些特定于某个请求的状态变化。当处理请求结束,request作用域的bean实例将被销毁。

当一个bean的作用域为Session,表示在一个HTTPSession中,一个bean定义对应一个实例。该作用域仅在基于web的SpringApplicationContext情形下有效。考虑下面bean定义:

针对某个HTTPSession,Spring容器会根据userPreferencesbean定义创建一个全新的userPreferencesbean实例,且该userPreferencesbean仅在当前HTTPSession内有效。与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTPSession中根据userPreferences创建的实例,将不会看到这些特定于某个HTTPSession的状态变化。当HTTPSession最终被废弃的时候,在该HTTPSession作用域内的bean也会被废弃掉。

在Spring中有三种装配的方式

这里我们主要讲第三种:自动化的装配bean。

Spring的自动装配需要从两个角度来实现,或者说是两个操作:

组件扫描和自动装配组合发挥巨大威力,使得显示的配置降低到最少。

推荐不使用自动装配xml配置,而使用注解.

测试环境搭建

1、新建一个项目

2、新建两个实体类,CatDog都有一个叫的方法

publicclassCat{publicvoidshout(){System.out.println("miao~");}}publicclassDog{publicvoidshout(){System.out.println("wang~");}}3、新建一个用户类User

publicclassPeople{privateCatcat;privateDogdog;privateStringstr;//set与get}4、编写Spring配置文件

publicclassMyTest{@Testpublicvoidtest1(){ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml");Peoplepeople=context.getBean("people",People.class);people.getCat().shout();people.getDog().shout();}}结果正常输出,环境OK

环境搭建:一个人有两个宠物

7.3byTpye自动装配 小结:

jdk1.5支持的注解,Spring2.5就支持注解了!

要使用注解须知:

使用Autowired我们可以不用编写set方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byName

publicclassPeople{@AutowiredprivateCatcat;@AutowiredprivateDogdog;privateStringstr;publicCatgetCat(){returncat;}publicvoidsetCat(Catcat){this.cat=cat;}publicDoggetDog(){returndog;}}科普:

@Nullable 字段标记了这个注解,说明这个字段可以为null;public@interfaceAutowired{booleanrequired()defaulttrue;}测试代码:

publicclassPeople{//如果显示定义了Autowired的required属性为false,说明这个对象可以为Null,否则不允许为空@Autowired(required=false)privateCatcat;@AutowiredprivateDogdog;privateStringname;}如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value=“xxx”)去配合@Autowire的使用,指定一个唯一的bean对象注入!

publicclassPeople{@Autowired@Qualifier(value="cat2")privateCatcat;@AutowiredprivateDogdog;privateStringname;}@Resource@Resource如有指定的name属性,先按该属性进行byName方式查找装配;其次再进行默认的byName方式进行装配;如果以上都不成功,则按byType的方式自动装配。都不成功,则报异常。结论:先进行byName查找,失败;再进行byType查找,成功。

publicclassPeople{@Resource(name="cat3")privateCatcat;@ResourceprivateDogdog;privateStringname;}小结:

@Autowired与@Resource异同:

1、@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。

2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false),如果我们想使用名称装配可以结合@Qualifier注解进行使用

3、@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。

说明

在spring4之后,想要使用注解形式,必须得要引入aop的包

在配置文件当中,还得要引入一个context约束

我们之前都是使用bean的标签进行bean注入,但是实际开发中,我们一般都会使用注解!

1、配置扫描哪些包下的注解

2、在指定包下编写类,增加注解

@Component("user")//相当于配置文件中publicclassUser{publicStringname="sdz";}3、测试

@Testpublicvoidtest(){ApplicationContextapplicationContext=newClassPathXmlApplicationContext("beans.xml");Useruser=(User)applicationContext.getBean("user");System.out.println(user.name);}属性注入

使用注解注入属性

1、可以不用提供set方法,直接在直接名上添加@value("值")

@Component("user")//相当于配置文件中publicclassUser{@Value("sdz")//相当于配置文件中publicStringname;}2、如果提供了set方法,在set方法上添加@value("值");

@Component("user")publicclassUser{publicStringname;@Value("sdz")publicvoidsetName(Stringname){this.name=name;}}衍生注解

我们这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷!

@Component三个衍生注解

为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。

写上这些注解,就相当于将这个类交给Spring管理装配了!

这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean

自动装配注解

在Bean的自动装配。

-@Autowired:自动装配通过类型。名字如果Autowired不能唯-。-自动装配上属性,则需要通过@Qualifier(value=“xxx”)-@Nullable字段标记了这个注解,说明这个字段可以为null;-@Resource:自动装配通过名字。类型作用域

@scope

@Controller("user")@Scope("prototype")publicclassUser{@Value("sdz")publicStringname;}小结

XML与注解比较

xml与注解整合开发:推荐最佳实践

作用:

进行注解驱动注册,从而使注解生效

用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册

如果不扫描包,就需要手动配置bean

如果不加注解驱动,则注入的值为null!

JavaConfig原来是Spring的一个子项目,它通过Java类的方式提供Bean的定义信息,在Spring4的版本,JavaConfig已正式成为Spring4的核心功能。

测试:

1、编写一个实体类,Dog

//这里这个注解的意思,就是说明这个类被Spring接管了,注册到人气中@ComponentpublicclassUser{privateStringname;publicStringgetName(){returnname;}@Value("sdz")//注册值publicvoidsetName(Stringname){this.name=name;}@OverridepublicStringtoString(){return"User{"+"name='"+name+'\''+'}';}}2、新建一个config配置包,编写一个SdzConfig配置类

@Configuration//这个也会被spring容器托管,注册到容器中。//因为它本来就是一个@Component,@Configuration代表这是一个配置类,等价于beans.xml@ComponentScan("com.sdz")//扫描包publicclassSdzConfig{//注册一个Bean,相当于我们之前写的一个bean标签//这个方法的名字,就相当于bean标签中的id属性//这个方法的返回值,就相当于bean标签中的class属性@BeanpublicUsergetUser(){returnnewUser();//就是返回要注入bean的对象}}3、测试

publicclassMyTest{@Testpublicvoidtest1(){//如果完全使用了配置类方式去做,我们就只能通过AnnotationConfig上下文来获收容器,通过配置类的cLass对象加载!ApplicationContextcontext=newAnnotationConfigApplicationContext(SdzConfig.class);UsergetUser=(User)context.getBean("getUser");System.out.println(getUser.getName());}}4、成功输出结果!

导入其他配置如何做呢?

1、我们再编写一个配置类!

@Configuration//代表这是一个配置类publicclassMyConfig2{}2、在之前的配置类中我们来选择导入这个配置类

@Configuration@Import(MyConfig2.class)//导入合并其他配置类,类似于配置文件中的inculde标签publicclassMyConfig{@BeanpublicDogdog(){returnnewDog();}}关于这种Java类的配置方式,我们在之后的SpringBoot和SpringCloud中还会大量看到,我们需要知道这些注解的作用即可!

为什么要学习代理模式,因为AOP的底层机制就是动态代理!

代理模式:

学习aop之前,我们要先了解一下代理模式!

静态代理角色分析

抽象角色:一般使用接口或者抽象类来实现

真实角色:被代理的角色

代理角色:代理真实角色;代理真实角色后,一般会做一些附属的操作.

客户:使用代理角色来进行一些操作.

代码实现

Rent.java即抽象角色

//抽象角色:租房publicinterfaceRent{publicvoidrent();}Host.java即真实角色

//真实角色:房东,房东要出租房子publicclassHostimplementsRent{publicvoidrent(){System.out.println("房屋出租");}}Proxy.java即代理角色

//代理角色:中介publicclassProxyimplementsRent{privateHosthost;publicProxy(){}publicProxy(Hosthost){this.host=host;}//租房publicvoidrent(){seeHouse();host.rent();fare();}//看房publicvoidseeHouse(){System.out.println("带房客看房");}//收中介费publicvoidfare(){System.out.println("收中介费");}}Client.java即客户

//客户类,一般客户都会去找代理!publicclassClient{publicstaticvoidmain(String[]args){//房东要租房Hosthost=newHost();//中介帮助房东租房Proxyproxy=newProxy(host);//你去找中介!proxy.rent();}}分析:在这个过程中,你直接接触的就是中介,就如同现实生活中的样子,你看不到房东,但是你依旧租到了房东的房子通过代理,这就是所谓的代理模式,程序源自于生活,所以学编程的人,一般能够更加抽象的看待生活中发生的事情。

静态代理的好处:

缺点:

我们想要静态代理的好处,又不想要静态代理的缺点,所以,就有了动态代理!

练习步骤:

1、创建一个抽象角色,比如咋们平时做的用户业务,抽象起来就是增删改查!

//抽象角色:增删改查业务publicinterfaceUserService{voidadd();voiddelete();voidupdate();voidquery();}2、我们需要一个真实对象来完成这些增删改查操作

//真实对象,完成增删改查操作的人publicclassUserServiceImplimplementsUserService{publicvoidadd(){System.out.println("增加了一个用户");}publicvoiddelete(){System.out.println("删除了一个用户");}publicvoidupdate(){System.out.println("更新了一个用户");}publicvoidquery(){System.out.println("查询了一个用户");}}3、需求来了,现在我们需要增加一个日志功能,怎么实现!

4、设置一个代理类来处理日志!代理角色

//代理角色,在这里面增加日志的实现publicclassUserServiceProxyimplementsUserService{privateUserServiceImpluserService;publicvoidsetUserService(UserServiceImpluserService){this.userService=userService;}publicvoidadd(){log("add");userService.add();}publicvoiddelete(){log("delete");userService.delete();}publicvoidupdate(){log("update");userService.update();}publicvoidquery(){log("query");userService.query();}publicvoidlog(Stringmsg){System.out.println("执行了"+msg+"方法");}}5、测试访问类:

publicclassClient{publicstaticvoidmain(String[]args){//真实业务UserServiceImpluserService=newUserServiceImpl();//代理类UserServiceProxyproxy=newUserServiceProxy();//使用代理类实现日志功能!proxy.setUserService(userService);proxy.add();}}OK,到了现在代理模式大家应该都没有什么问题了,重点大家需要理解其中的思想;

我们在不改变原来的代码的情况下,实现了对原有功能的增强,这是AOP中最核心的思想

聊聊AOP:纵向开发,横向开发

动态代理的角色和静态代理的一样.

动态代理的代理类是动态生成的。静态代理的代理类是我们提前写好的

动态代理分为两类:一类是基于接口动态代理,一类是基于类的动态代理

JDK的动态代理需要了解两个类

核心:InvocationHandler和Proxy,打开JDK帮助文档看看

【InvocationHandler:是由代理实例的调用处理程序实现的接口。】

//生成代理类publicObjectgetProxy(){returnProxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);}代码实现

抽象角色和真实角色和之前的一样!

//真实角色:房东,房东要出租房子publicclassHostimplementsRent{publicvoidrent(){System.out.println("房屋出租");}}ProxyInvocationHandler.java即代理角色

publicclassProxyInvocationHandlerimplementsInvocationHandler{privateRentrent;publicvoidsetRent(Rentrent){this.rent=rent;}//自动生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色publicObjectgetProxy(){returnProxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);}//proxy:代理类method:代理类的调用处理程序的方法对象.//处理代理实例上的方法调用并返回结果@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{seeHouse();//核心:本质利用反射实现!Objectresult=method.invoke(rent,args);fare();returnresult;}//看房publicvoidseeHouse(){System.out.println("带房客看房");}//收中介费publicvoidfare(){System.out.println("收中介费");}}Client.java

//租客publicclassClient{publicstaticvoidmain(String[]args){//真实角色Hosthost=newHost();//代理实例的调用处理程序ProxyInvocationHandlerpih=newProxyInvocationHandler();pih.setRent(host);//将真实角色放置进去!Rentproxy=(Rent)pih.getProxy();//动态生成对应的代理类!proxy.rent();}}核心:一个动态代理,一般代理某一类业务,一个动态代理可以代理多个类,代理的是接口!、

我们来使用动态代理实现代理我们后面写的UserService!

我们也可以编写一个通用的动态代理实现的类!所有的代理对象设置为Object即可!

publicclassProxyInvocationHandlerimplementsInvocationHandler{privateObjecttarget;publicvoidsetTarget(Objecttarget){this.target=target;}//生成代理类publicObjectgetProxy(){returnProxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}//proxy:代理类//method:代理类的调用处理程序的方法对象.publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{log(method.getName());Objectresult=method.invoke(target,args);returnresult;}publicvoidlog(StringmethodName){System.out.println("执行了"+methodName+"方法");}}测试!

publicclassTest{publicstaticvoidmain(String[]args){//真实对象UserServiceImpluserService=newUserServiceImpl();//代理对象的调用处理程序ProxyInvocationHandlerpih=newProxyInvocationHandler();pih.setTarget(userService);//设置要代理的对象UserServiceproxy=(UserService)pih.getProxy();//动态生成代理类!proxy.delete();}}测试,增删改查,查看结果!

静态代理有的它都有,静态代理没有的,它也有!

什么是AOP

AOP(AspectOrientedProgramming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

Aop在Spring中的作用

以下名词需要了解下:

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

即Aop在不改变原有代码的情况下,去增加新的功能.

使用Spring实现Aop

【重点】使用AOP织入,需要导入一个依赖包!

通过SpringAPI实现

首先编写我们的业务接口和实现类(service包下)

publicinterfaceUserService{publicvoidadd();publicvoiddelete();publicvoidupdate();publicvoidsearch();}publicclassUserServiceImplimplementsUserService{@Overridepublicvoidadd(){System.out.println("增加用户");}@Overridepublicvoiddelete(){System.out.println("删除用户");}@Overridepublicvoidupdate(){System.out.println("更新用户");}@Overridepublicvoidsearch(){System.out.println("查询用户");}}然后去写我们的增强类,我们编写两个,一个前置增强一个后置增强(log包下)

publicclassLogimplementsMethodBeforeAdvice{//method:要执行的目标对象的方法//objects:被调用的方法的参数//Object:目标对象@Overridepublicvoidbefore(Methodmethod,Object[]objects,Objecto)throwsThrowable{System.out.println(o.getClass().getName()+"的"+method.getName()+"方法被执行了");}}publicclassAfterLogimplementsAfterReturningAdvice{//returnValue返回值//method被调用的方法//args被调用的方法的对象的参数//target被调用的目标对象@OverridepublicvoidafterReturning(ObjectreturnValue,Methodmethod,Object[]args,Objecttarget)throwsThrowable{System.out.println("执行了"+target.getClass().getName()+"的"+method.getName()+"方法,"+"返回值:"+returnValue);}}最后去spring的文件中注册,并实现aop切入实现,注意导入约束.

publicclassMyTest{@Testpublicvoidtest(){ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml");//动态代理代理的是接口UserServiceuserService=(UserService)context.getBean("userService");userService.search();}}Aop的重要性:很重要.一定要理解其中的思路,主要是思想的理解这一块.

Spring的Aop就是将公共的业务(日志,安全等)和领域业务结合起来,当执行领域业务时,将会把公共业务加进来.实现公共业务的重复利用.领域业务更纯粹,程序猿专注领域业务,其本质还是动态代理.

第二种方式

自定义类来实现Aop

目标业务类不变依旧是userServiceImpl

第一步:写我们自己的一个切入类(config包下)

publicclassDiyPointcut{publicvoidbefore(){System.out.println("---------方法执行前---------");}publicvoidafter(){System.out.println("---------方法执行后---------");}}去spring中配置

测试:

publicclassMyTest{@Testpublicvoidtest(){ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml");//动态代理代理的是接口UserServiceuserService=(UserService)context.getBean("userService");userService.add();}}第三种方式

使用注解实现

第一步:编写一个注解实现的增强类

packagecom.sdz.config;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.After;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;@AspectpublicclassAnnotationPointcut{@Before("execution(*com.sdz.service.UserServiceImpl.*(..))")publicvoidbefore(){System.out.println("---------方法执行前---------");}@After("execution(*com.sdz.service.UserServiceImpl.*(..))")publicvoidafter(){System.out.println("---------方法执行后---------");}@Around("execution(*com.sdz.service.UserServiceImpl.*(..))")publicvoidaround(ProceedingJoinPointjp)throwsThrowable{System.out.println("环绕前");System.out.println("签名:"+jp.getSignature());//执行目标方法proceedObjectproceed=jp.proceed();System.out.println("环绕后");System.out.println(proceed);}}第二步:在Spring配置文件中,注册bean,并增加支持注解的配置

aop:aspectj-autoproxy:说明

junit

junitjunit4.12mybatis

org.mybatismybatis3.5.2mysql-connector-java

org.springframeworkspring-webmvc5.1.10.RELEASEorg.springframeworkspring-jdbc5.1.10.RELEASEaspectJAOP织入器

org.mybatismybatis-spring2.0.2lombok

org.projectlomboklombok1.18.10配置Maven静态资源过滤问题!

src/main/java**/*.properties**/*.xmltrue2、编写配置文件

3、代码实现

编写pojo实体类

packagecom.sdz.pojo;importlombok.Data;@DatapublicclassUser{privateintid;//idprivateStringname;//姓名privateStringpwd;//密码}实现mybatis的配置文件(mybatis-config.xml)

publicinterfaceUserMapper{publicListselectUser();}接口对应的Mapper映射文件

packagecom.sdz.utils;importorg.apache.ibatis.io.Resources;importorg.apache.ibatis.session.SqlSession;importorg.apache.ibatis.session.SqlSessionFactory;importorg.apache.ibatis.session.SqlSessionFactoryBuilder;importjava.io.IOException;importjava.io.InputStream;//sqlSessionFactory-->sqlSessionpublicclassMybatisUtils{privatestaticSqlSessionFactorysqlSessionFactory;static{try{//使用Mybatis第一步:获取sqlSessionFactory对象Stringresource="mybatis-config.xml";InputStreaminputStream=Resources.getResourceAsStream(resource);sqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);}catch(IOExceptione){e.printStackTrace();}}//既然有了SqlSessionFactory,顾名思义,我们就可以从中获得SqlSession的实例了。//SqlSession完全包含了面向数据库执行SQL命令所需的所有方法。publicstaticSqlSessiongetSqlSession(){returnsqlSessionFactory.openSession();}}测试类

publicclassMyTest{@Testpublicvoidtest(){SqlSessionsqlSession=MybatisUtils.getSqlSession();UserMapperuserMapper=sqlSession.getMapper(UserMapper.class);ListuserList=userMapper.selectUser();for(Useruser:userList){System.out.println(user);}sqlSession.close();}}MyBatis-Spring学习引入Spring之前需要了解mybatis-spring包中的一些重要类;

什么是MyBatis-Spring?

MyBatis-Spring会帮助你将MyBatis代码无缝地整合到Spring中。

知识基础

在开始使用MyBatis-Spring之前,你需要先熟悉Spring和MyBatis这两个框架和有关它们的术语。这很重要

MyBatis-Spring需要以下版本:

如果使用Maven作为构建工具,仅需要在pom.xml中加入以下代码即可:

org.mybatismybatis-spring2.0.2要和Spring一起使用MyBatis,需要在Spring应用上下文中定义至少两样东西:一个SqlSessionFactory和至少一个数据映射器类。

在MyBatis-Spring中,可使用SqlSessionFactoryBean来创建SqlSessionFactory。要配置这个工厂bean,只需要把下面代码放在Spring的XML配置文件中:

注意:SqlSessionFactory需要一个DataSource(数据源)。这可以是任意的DataSource,只需要和配置其它Spring数据库连接一样配置它就可以了。

在基础的MyBatis用法中,是通过SqlSessionFactoryBuilder来创建SqlSessionFactory的。而在MyBatis-Spring中,则使用SqlSessionFactoryBean来创建。

在MyBatis中,你可以使用SqlSessionFactory来创建SqlSession。一旦你获得一个session之后,你可以使用它来执行映射了的语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭session。

SqlSessionFactory有一个唯一的必要属性:用于JDBC的DataSource。这可以是任意的DataSource对象,它的配置方法和其它Spring数据库连接是一样的。

一个常用的属性是configLocation,它用来指定MyBatis的XML配置文件路径。它在需要修改MyBatis的基础配置非常有用。通常,基础配置指的是元素。

需要注意的是,这个配置文件并不需要是一个完整的MyBatis配置。确切地说,任何环境配置(),数据源()和MyBatis的事务管理器()都会被忽略。SqlSessionFactoryBean会创建它自有的MyBatis环境配置(Environment),并按要求设置自定义环境的值。

SqlSessionTemplate是MyBatis-Spring的核心。作为SqlSession的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的SqlSession。

模板可以参与到Spring的事务管理中,并且由于其是线程安全的,可以供多个映射器类使用,你应该总是用SqlSessionTemplate来替换MyBatis默认的DefaultSqlSession实现。在同一应用程序中的不同类之间混杂使用可能会引起数据一致性的问题。

可以使用SqlSessionFactory作为构造方法的参数来创建SqlSessionTemplate对象。

现在,这个bean就可以直接注入到你的DAObean中了。你需要在你的bean中添加一个SqlSession属性,就像下面这样:

publicclassUserDaoImplimplementsUserDao{privateSqlSessionsqlSession;publicvoidsetSqlSession(SqlSessionsqlSession){this.sqlSession=sqlSession;}publicUsergetUser(StringuserId){returnsqlSession.getMapper...;}}按下面这样,注入SqlSessionTemplate:

整合实现一1、引入Spring配置文件spring-dao.xml

3、配置SqlSessionFactory,关联MyBatis

4、注册sqlSessionTemplate,关联sqlSessionFactory;

5、增加UserMapper接口的实现类;私有化sqlSessionTemplate

publicclassUserMapperImplimplementsUserMapper{//sqlSession不用我们自己创建了,Spring来管理privateSqlSessionTemplatesqlSession;publicvoidsetSqlSession(SqlSessionTemplatesqlSession){this.sqlSession=sqlSession;}publicListselectUser(){UserMappermapper=sqlSession.getMapper(UserMapper.class);returnmapper.selectUser();}}6、注册bean实现

7、测试

publicclassMyTest{@Testpublicvoidtest(){ApplicationContextcontext=newClassPathXmlApplicationContext("spring-dao.xml");UserMappermapper=(UserMapper)context.getBean("userMapper");ListuserList=mapper.selectUser();for(Useruser:userList){System.out.println(user);}}}结果成功输出!现在我们的Mybatis配置文件的状态!发现都可以被Spring整合!

更明确分工整合

spring-dao.xml

mybatis-spring1.2.3版以上的才有这个.

官方文档截图:

dao继承Support类,直接利用getSqlSession()获得,然后直接注入SqlSessionFactory.比起方式1,不需要管理SqlSessionTemplate,而且对事务的支持更加友好.可跟踪源码查看

1、将我们上面写的UserDaoImpl修改一下

publicclassUserMapperImpl2extendsSqlSessionDaoSupportimplementsUserMapper{publicListselectUser(){UserMappermapper=getSqlSession().getMapper(UserMapper.class);returnmapper.selectUser();}}2、修改bean的配置

3、测试

@Testpublicvoidtest(){ApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");UserMappermapper=(UserMapper)context.getBean("userMapper2");ListuserList=mapper.selectUser();for(Useruser:userList){System.out.println(user);}}总结:整合到spring以后可以完全不要mybatis的配置文件,除了这些方式可以实现整合之外,我们还可以使用注解来实现,这个等我们后面学习SpringBoot的时候还会测试整合!

事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。

事务四个属性ACID

原子性(atomicity)

一致性(consistency)

隔离性(isolation)

持久性(durability)

将上面的代码拷贝到一个新项目中

在之前的案例中,我们给userMapper接口新增两个方法,删除和增加用户;

//添加一个用户intaddUser(Useruser);//根据id删除用户intdeleteUser(intid);mapper文件,我们故意把deletes写错,测试!

insertintouser(id,name,pwd)values(#{id},#{name},#{pwd})deletesfromuserwhereid=#{id}编写接口的实现类,在实现类中,我们去操作一波

publicclassUserMapperImplextendsSqlSessionDaoSupportimplementsUserMapper{//增加一些操作publicListselectUser(){Useruser=newUser(10,"小明","123456");UserMappermapper=getSqlSession().getMapper(UserMapper.class);mapper.addUser(user);mapper.deleteUser(4);returnmapper.selectUser();}//新增publicintaddUser(Useruser){UserMappermapper=getSqlSession().getMapper(UserMapper.class);returnmapper.addUser(user);}//删除publicintdeleteUser(intid){UserMappermapper=getSqlSession().getMapper(UserMapper.class);returnmapper.deleteUser(id);}}测试

@Testpublicvoidtest2(){ApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");UserMappermapper=(UserMapper)context.getBean("userMapper");Listuser=mapper.selectUser();System.out.println(user);}报错:sql异常,delete写错了

结果:插入成功!

没有进行事务的管理;我们想让他们都成功才成功,有一个失败,就都失败,我们就应该需要事务!

以前我们都需要自己手动管理事务,十分麻烦!

但是Spring给我们提供了事务管理,我们只需要配置即可;

Spring中的事务管理

编程式事务管理

使用Spring管理事务,注意头文件的约束导入:tx

JDBC事务

spring事务传播特性:

事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行为:

Spring默认的事务传播行为是PROPAGATION_REQUIRED,它适合于绝大多数的情况。

假设ServiveX#methodX()都工作在事务环境下(即都被Spring事务增强了),假设程序中存在如下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这3个服务类的3个方法通过Spring的事务传播机制都工作在同一个事务中。

就好比,我们刚才的几个方法存在调用,所以会被放在一组事务当中!

配置AOP

导入aop的头文件!

进行测试

删掉刚才插入的数据,再次测试!

@Testpublicvoidtest2(){ApplicationContextcontext=newClassPathXmlApplicationContext("applicationContext.xml");UserMappermapper=(UserMapper)context.getBean("userMapper");Listuser=mapper.selectUser();System.out.println(user);}

THE END
1.宠物司机宠物管家(宠托师)在快节奏的现代生活中,宠物已成为许多家庭不可或缺的一员,它们用无条件的爱与陪伴温暖着人们的心房。然而,随着工作与生活压力的增大,如何妥善照顾宠物,尤其是在主人忙碌或外出时,成为了一个亟待解决的问题。为此,宠拉达服务平台应运而生,它不仅连接了宠物与主人之间的情感纽带,更为宠物司机、宠物管家(宠托师)及宠...https://www.163.com/dy/article/JH437EBK05387C11.html
2.宠物回国宠物出国国内宠物托运多格儿货运有限公司是一家主营宠物托运的物流公司,自公司成立以来,凭借与各航空公司优良的合作关系,在我们每一个多格儿人的不懈努力下,以优质的全程跟踪服务,使得多格儿日益壮大,现已成为广东地区最大的宠物托运服务商之一。公司服务产品包括宠物国内航空托运、宠物出http://www.dogeer.cn/
3.宠物粮代理加盟费宠物粮代理加盟费是多少钱?有兴趣加盟的亲们,赶紧来了解一下详细的加盟费用资料吧!做好万全准备,才能够让创业之路走的更加顺畅!宠物粮代理加盟投资费用 宠物粮代理加盟费用: 宠物粮代理投资费用在11-26万元。 作为极其抢手的加盟品牌,宠物粮代理的加盟并不是那么容易,因此,对于有想法的投资者来说,最好是能够详细了解宠物粮代理的加盟政策...https://www.jiamengfei.com/xm/125845
4.宠物,饲料价格宠物,饲料注意事项④网上做企业税务登记及税务报道,一般是在电子税务局操作,也可以带上执照副本、法人身份复印件、公章、开户基本信息前往当地的税务局办理,现场办理一般是一早上或一下午即可。 (C)宠物饲料公司取名字参考大全2-3个字 参考一:柯维妙宠物饲料有限公司,火开宠物饲料有限公司,通廷腾宠物饲料有限公司,能妙宠物饲料有限公司...https://www.yinghuodd.com/keywords/word_25175.html
1.流动“铲屎官”来了你会为上门喂宠买单吗?“目前像嘻猫、猫巷这种比较大的专做上门喂宠的平台还没有在徐州开展业务,所以我一般都是在小红书或者闲鱼上发帖揽客。当然,老客户的口碑推荐也是非常重要的客源渠道。”林佳介绍,她从小就喜欢小动物,家里也一直有宠物陪伴。今年春节期间,她开始帮忙照看朋友们的宠物,后来逐渐发展成了她的一份兼职。 https://szb.cnxz.com.cn/dscb/pad/con/202411/21/content_24292.html
2.上海最新宠物店转让,探索宠物行业新机遇公司产品摘要:最新消息,上海某宠物店正在转让,为宠物行业爱好者带来全新机遇。这是一个探索宠物行业的理想时机,为宠物爱好者提供一个开设宠物店的机会,发掘宠物市场的潜力。有意者可以进一步了解详情,把握这一不容错过的商业机遇。 本文将详细探讨一起引人注目的上海宠物店转让事件,同时深入分析宠物行业市场状况及其未来发展前景...https://www.ferton.cn/post/22787.html
3.宠物行业新机遇:生态系统构建全解析与发展路径亲爱的读者朋友们,您是否曾想过,为什么近年来宠物行业发展如此迅猛?今天,我们将带您深入了解宠物行业生态系统的构建过程,揭示其中的关键要素与未来发展路径。让我们一同探索这个充满潜力的行业吧! 一、宠物行业概述 1.1 行业定义与范围 定义:宠物行业是一个涵盖宠物繁育、交易、食品、用品、医疗、服务等多元化产业链的...https://www.qika321.com/hangye/215.html
4.狗狗用品代理:我想做淘宝宠物用品代理前段时间对比过,后来是从宠爱商贸进的,感觉还是可以的,回头可以做个比较 我刚刚开始做代理,但是一直没有客源,很头疼,我是做宠物用品的 答: 是开宠物店的吗 那就是你的方向错了,经营的目标不对,无法找到自己的精准客户和潜在客户,所以现在没什么头绪,你最好是能够找到一家加盟品牌,虽然会花一点钱,但是对自己的...https://www.6gii.com/wenda/40823.html
5.广州进口宠物用品代理清关,进口宠物用品单证要求一般贸易清关...本文《广州进口宠物用品代理清关,进口宠物用品单证要求【一般贸易清关攻略】》由我司卓鹰上海报关公司发布,转载请声明! 上海卓鹰清关——提供海外提供|空运海运|进口清关|进口报关|代理报关|清关代理|进口货代|进口代理|外贸代理|国内派送|保税仓储服务,是靠谱的上海报关公司|上海清关公司|上海货代公司|上海保税仓储公司...http://www.zouin.net/h-nd-203284.html
6.大学夏令营注意事项2. 做代理商 做某个商品的代理,不需要占用全职的时间,而且正职的工作还能积累较多的人脉,方便代理商品的销售。 3. 咨询业 这是最常见到的一种在职创业类型。通常是在职者利用自己的头脑智慧、丰富的从业经验或专业技术,进行创业。 4. 委托投资 适合那些拥有一定资金,但个人缺少精力或时间的创业者。对于委托投资来...https://www.360wenmi.com/f/file5rekgu0b.html
7.“AI测面相”调查:宠物狗能得81分,分级推广类似传销云从科技研究院副院长周翔向南都记者表示,“AI测面相”仅仅是一种偏娱乐化的应用,基本没有什么可信度。“一般的是随机匹配一些提前编好的信息。可能会有认真一点的,会给不同人脸数据标注一些运势信息,然后进行训练,这样生成的结果会稳定一些。” 零门槛做“代理”, 99元可购买全套软件 ...https://news.southcn.com/node_17a07e5926/c71b46bc71.shtml
8.终于有人讲清楚了树莓派是什么3.一个宠物喂食机 一个超级有才华的用户使用树莓派电脑连接摄像头,并手工制造了机身。可以唉摄像头探测到狗狗接近的时候自动发放狗粮,非常方便。我倒是觉得可以应用到门锁上来。摄像头确定是否为设置者设置的人,然后在自动发放钥匙。估计市场比电子锁什么的要好,因为树莓派实在是太便宜。 https://m.elecfans.com/article/620717.html
9.=爬宠=爬宠,异宠出售可招代理宠物蛇宠物蜘蛛蜥蜴蝎子青蛙等=看够了美妆 来一点不同= 找代理哦 ,利润很大的~ 微信号:babymiwu 宠物蛇 宠物蜘蛛 宠物蝎子 宠物蜥蜴 宠物乌龟 宠物青蛙 龙猫 等等 宠物 保证最低价 保证状态好 所有宠物一对包邮 发货包运输风险 大家眼中的这些宠物可能很冷血 ,其实并不是的他们干净 温顺 胆小 喜欢依赖主人 所以我为大家挑选的保证无毒温顺...https://www.douban.com/group/topic/53187941/
10.宠物航空物流需办理《检疫合格证明》首先需要确定是自己办理,还是由代理去办理,如果是自行办理需要提前了解所在的城市、所选择的运输方式是否可以自己办理,如果是交付托运代理人办理,就按照他们的要求一步步做就行了。提供你的始发地、目的地、宠物品种(还有年龄)、重量,他们提供报价以及预定运输工具。 https://www.kllxg.com/64/view-74.html
11.b站硬核会员答题答案是什么b站硬核会员答题答案大全2023b站硬核会员答题答案是什么?b站之前推出的硬核会员机制最近又可以申请资格了,同样需要用户回答若干问题,相信很多小伙伴都被这些问题难住了吧。不要慌这里小编给大家带来了b站硬核会员答题答案大全,相信能帮助到有需要的小伙伴们,话不多说一起来了解看看吧。 https://app.3dmgame.com/gl/430491.html
12.我的三个宠物狗总是让我很忙。我打算把其中两只送给朋友。【单选题】视神经乳头中央的凹陷区称做( )。 查看完整题目与答案 【单选题】灭鼠工作中最重要的一种方法是经常进行搬家式的大扫除,它属于( )。 查看完整题目与答案 【单选题】视盘对应的视野区域是( )。 查看完整题目与答案 【单选题】食品容器消毒“四过关”的内容是( )。 查看完整题目与...https://www.shuashuati.com/ti/10bdcd1309634bb1985f2a0ee3bdaf1b.html?fm=bdbds963c16c7bd57ba3de3bb468852922782
13.如何做成功的项目管理8篇(全文)大量事实证明,市场批发不仅风险系数、利润率、市场竞争比不过品牌代理,而且从宏观的产业发展趋势分析,市场批发已近夕阳,而从事特许品牌代理,则是从事服装销售者的金光大道。那如何才能做一个成功的品牌代理呢? 简单夹说,就是要伺机而动,量力而行。所谓的“机”和“力”,就是成功运作品牌代理的必备条件,时下的服装...https://www.99xueshu.com/w/fileae0xt35t.html
14.这48条法律常识你知道吗?要是你没证据证明时对方挑逗激怒宠物咬伤了他,那你就乖乖承担医药费吧。 19、高空抛物 一栋楼上某户人家中丢了某个物件砸伤了人,除1楼外的高层都可能被判承担责任。除非,你能证明你当时家中空无一人。 20、竞技体育受伤 竞技体育中的人身损害除非严重违反规则或故意伤害,否则排除侵权法适用。 http://www.pdrmtzx.com/2022/0621/103675.html
15.怎么接托运的猫咪空运猫咪的方法托运当天带上宠物、笼子、***、***及上述三证,提前四个小时到火车站托运处***托运。 火车托运要求也比较严格,所以相关证明也需要准备齐全。目前火车托运很多采用了第三方公司委托代理的方式,但是在管理上不是那么严格。如果要选择第三方公司托运,要认真选择一家靠谱的。http://m.boqii.com/article/74356.html
16.宠物店创新创业计划书(通用7篇)爱心:首先员工要有爱心,热爱宠物,尊重生命,把宠物当做朋友。 责任心:敬业爱岗,顾客至上,用心服务。 事业心:熟练掌握宠物商品知识,熟知各种宠物的性格特点,熟练掌握各种服务技能,将宠物事业作为职业追求 2)货品选择保证质量:时刻牢记我们是为生命服务的,对于一般人只有猫、狗的概念,但对于饲养宠物的顾客群来说,宠物就...https://www.oh100.com/kaidian/4689055.html