Get started Spring
1. Write a Hello entity class
public class Hello { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("Hello,"+ name ); } }
2. Write the Spring file, which is named beans 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--bean namely java object , from Spring Create and manage--> <bean id="hello" class="com.kuang.pojo.Hello"> <property name="name" value="Spring"></property> </bean> </beans>
3. Test
@Test public void test(){ //Parse beans XML file to generate and manage the corresponding Bean objects ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //getBean: the parameter is the id of the bean in the spring configuration file Hello hello = (Hello) context.getBean("hello"); hello.show(); }
Modify case 1
We have added a Spring configuration file beans 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="MysqlImpl" class="com.kuang.dao.impl.UserDaoMySqlImpl"/> <bean id="OracleImpl" class="com.kuang.dao.impl.UserDaoOracleImpl"/> <bean id="ServiceImpl" class="com.kuang.service.impl.UserServiceImpl"> <!--be careful: there name Is not an attribute , But set The part behind the method , Initial lowercase--> <!--Reference another bean , Not with value But with ref--> <property name="userDao" ref="OracleImpl"/> </bean> </beans>
test
ApplicationContext context =new ClassPathXmlApplicationContext("beans.xml"); UserServiceImpl serviceImpl=context.getbean("ServiceImpl",ServiceImpl.class); serviceImpl.getUser();
IOC creation - implemented by parameterless construction method
1.User.java
public class User { private String name; public User() { System.out.println("user Nonparametric construction method"); } public void setName(String name) { this.name = name; } public void show(){ System.out.println("name="+ name ); } }
2.beans.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="com.kuang.pojo.User"> <property name="name" value="kuangshen"/> </bean> </beans>
3. Testing
public void test(){ ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml"); User user=context.getBean("user"); user.show(); }
Ioc is created through a parametric construct
1. Create entity class
public class UserT { private String name; public UserT(String name) { this.name = name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("name="+ name ); } }
2.beans. Three ways to write XML
<!-- First basis index Parameter subscript setting --> <bean id="userT" class="com.kuang.pojo.UserT"> <!-- index Refers to the construction method , Subscript starts at 0 --> <constructor-arg index="0" value="kuangshen2"/> </bean>
<!-- The second is set according to the parameter name --> <bean id="userT" class="com.kuang.pojo.UserT"> <!-- name Refers to the parameter name --> <constructor-arg name="name" value="kuangshen2"/> </bean>
<!-- The third is set according to the parameter type --> <bean id="userT" class="com.kuang.pojo.UserT"> <constructor-arg type="java.lang.String" value="kuangshen2"/> </bean>
Configuration of aliases in Spring
<!--Setting alias: getting Bean You can use alias to get--> <alias name="userT" alias="userNew"/>
Dependency injection in Spring
1.Address.java class
public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
2.Student.java
package com.kuang.pojo; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class Student { private String name; private Address address; private String[] books; private List<String> hobbys; private Map<String,String> card; private Set<String> games; private String wife; private Properties info; public void setName(String name) { this.name = name; } public void setAddress(Address address) { this.address = address; } public void setBooks(String[] books) { this.books = books; } public void setHobbys(List<String> hobbys) { this.hobbys = hobbys; } public void setCard(Map<String, String> card) { this.card = card; } public void setGames(Set<String> games) { this.games = games; } public void setWife(String wife) { this.wife = wife; } public void setInfo(Properties info) { this.info = info; } public void show(){ System.out.println("name="+ name + ",address="+ address.getAddress() + ",books=" ); for (String book:books){ System.out.print("<<"+book+">>\t"); } System.out.println("\n hobby:"+hobbys); System.out.println("card:"+card); System.out.println("games:"+games); System.out.println("wife:"+wife); System.out.println("info:"+info); } }
1. Constant injection
<bean id="student" class="com.kuang.pojo.Student"> <property name="name" value="Xiao Ming"/> </bean>
– testing
@Test public void test01(){ Application context=new ClassPathXmlApplicationContext("applicationContext.xml"); Student student=context.getBean("studnet",Studnet.class); System.out.println(student.getName()); }
2.Bean injection
<bean id="addr" class="com.kuang.pojo.Address"> <propery name="address" value="Chongqing"/> </bean> <bean id="Student" class="com.kuang.pojo.Student"> <property name="name" value="Xiao Ming"/> <property name="address" ref="addr"/> </bean>
3. Array injection
<bean id="student" class="com.kuang.pojo.Student"> <property name="name" value="Xiao Ming"/> <property name="address" ref="addr"/> <property name="books"> <array> <value>Journey to the West</value> <value>The Dream of Red Mansion</value> </array>
4.list injection
<property name="hobbys"> <list> <vlaue>listen to the music</value> <value>watch movie</value> </list> <property>
5.set injection
<property name="games"> <set> <value>LOL</value> <value>BOB</value> <value>COC</value> </set> </property>
6.map injection
<property name="card"> <map> <entry key="China Post" value="4435345353453"> <entry key="build" value="432143124132"> </map> </property>
Singleton mode
<bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">
Prototype mode
<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/> perhaps <bean id="account" class="com.foo.DefaultAccount" singleton="false"/>
Session scope
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
Automatic assembly of Bean
1. Create a new project
Create two new entity classes
public class Cat { public void shout() { System.out.println("miao~"); } }
public class Dog { public void shout() { System.out.println("wang~"); } }
public class User { private Cat cat; private Dog dog; private String str; }
2. Write Spring configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User"> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> <property name="str" value="qinjiang"/> </bean> </beans>
3. Test
public class MyTest { @Test public void testMethodAutowire() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = (User) context.getBean("user"); user.getCat().shout(); user.getDog().shout(); } }
Small exercise:
Modify the bean configuration and add an attribute autowire = "byName"
<bean id="user" class="com.kuang.pojo.User" autowire="byName"> <property name="str" value="qingjiang"/> </bean>
2. Test again and the result is still output successfully!
3. We modify the bean id of cat to catXXX
4. Test again and execute the null pointer Java lang.NullPointerException. Because the wrong set method is found according to the byName rule, the real setCat is not executed and the object is not initialized, so a null pointer error will be reported when calling.
Summary
When a bean node has an autowire byName attribute.
- All set method names in its class, such as setCat, will be searched to obtain a string with set removed and lowercase, that is, cat.
- Go to the spring container to find whether there is an object with this string name id.
- If any, take out the injection; If not, a null pointer exception is reported.
Modify the bean configuration and add an attribute autowire = "byType"
<bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="cat2" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User" autowire="byType"> <property name="str" value="qinjiang"/> </bean>
4. Test, error: NoUniqueBeanDefinitionException
5. Delete cat2 and change the bean name of cat! Test! Because it is assembled by type, no exception will be reported and the final result will not be affected. Even removing the id attribute does not affect the result.
This is automatic assembly by type!
Automatic assembly using annotations
1. Import the context file header into the spring configuration file
xmlns:context="http://www.springframework.org/schema/context"
2. Enable attribute annotation support
<context:annotation-config/>
@Autowired
- @Autowired is automatically transferred by type and does not support id matching.
- You need to import the package of spring AOP!
1. Removing the set method from the User class is the same as the @ Autowired annotation
public class User { @Autowired private Cat cat; @Autowired private Dog dog; private String str; public Cat getCat() { return cat; } public Dog getDog() { return dog; } public String getStr() { return str; } }
2. The content of the configuration file is displayed
<context:annotation-config/> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User"/>
@Qualifier
- @Autowired is automatically assembled according to the type. With @ Qualifier, it can be automatically assembled according to byName
- @Qualifier cannot be used alone.
1. Modification of configuration file
<bean id="dog1" class="com.kuang.pojo.Dog"/> <bean id="dog2" class="com.kuang.pojo.Dog"/> <bean id="cat1" class="com.kuang.pojo.Cat"/> <bean id="cat2" class="com.kuang.pojo.Cat"/>
2. If the Qualifier test is not added, an error is reported directly
3. Add Qualifier annotation on the attribute
@Aurowired @Qualifier(value="cat2") private Cat cat; @Autowired @Qualifier(value="dog2") private Dog dog;
@Resource
- @If the Resource has a specified name attribute, first search the assembly by name according to the attribute;
- Secondly, assemble in the default byName mode;
- If none of the above is successful, it will be assembled automatically by byType.
- If they are not successful, an exception is reported.
Entity class
public class User { //If the allowed object is null, set required = false, and the default is true @Resource(name = "cat2") private Cat cat; @Resource private Dog dog; private String str; }
beans.xml
<bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat1" class="com.kuang.pojo.Cat"/> <bean id="cat2" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User"/>
@Autowired And@Resource Similarities and differences: 1,@Autowired And@Resource Can be used to assemble bean. Can be written on the field or on the setter Method. 2,@Autowired Default assembly by type of spring Specification). By default, dependent objects must exist if they are allowed null Value, you can set its required Attribute is false,For example:@Autowired(required=false) ,If we want to use the name, the assembly can be combined@Qualifier Use annotations 3,@Resource(belong to J2EE Repeat), assemble by name by default, and the name can be name Property. If not specified name Property. When the annotation is written on a field, the field name is taken by default to search by name. If the annotation is written on setter The default attribute name on the method is used for assembly. When no matching name is found bean Assemble according to type only when. But it should be noted that if name Once the attribute is specified, it will only be assembled by name. They have the same function. They inject objects by annotation, but the execution order is different.@Autowired before byType,@Resource before byName.
Static / dynamic proxy mode
case
1.rent.java (Abstract role)
//Abstract role: rent a house public interface Rent { public void rent(); }
2.Host. Java (real role)
public class host implements Rent{ public void rent(){ System.out.println("House rental"); } }
proxy.java
//Agent role: Intermediary public class Proxy implements Rent { private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } //Rent a house public void rent(){ seeHouse(); host.rent(); fare(); } //House viewing public void seeHouse(){ System.out.println("Show the tenant"); } //Intermediary fee public void fare(){ System.out.println("Intermediary fee"); } }
Client is the customer
//Customers, general customers will find agents! public class Client { public static void main(String[] args) { //The landlord wants to rent a house Host host = new Host(); //The intermediary helps the landlord Proxy proxy = new Proxy(host); //You go to the agency! proxy.rent(); } }
Benefits of static proxy: making the business layer more convenient
Create an abstract role, such as the user business we usually do, which is abstracted to add, delete, modify and check!
//Abstract role: add, delete, modify and query business public interface UserService { void add(); void delete(); void update(); void query(); }
//Real object, the person who completes the operation of addition, deletion, modification and query public class UserServiceImpl implements UserService { public void add() { System.out.println("Added a user"); } public void delete() { System.out.println("A user was deleted"); } public void update() { System.out.println("A user has been updated"); } public void query() { System.out.println("A user was queried"); } }
Add agent logs to it
//Agent role, in which the implementation of log is added public class UserServiceProxy implements UserService { private UserServiceImpl userService; public void setUserService(UserServiceImpl userService) { this.userService = userService; } public void add() { log("add"); userService.add(); } public void delete() { log("delete"); userService.delete(); } public void update() { log("update"); userService.update(); } public void query() { log("query"); userService.query(); } public void log(String msg){ System.out.println("Yes"+msg+"method"); } }
public class Client { public static void main(String[] args) { //Real business UserServiceImpl userService = new UserServiceImpl(); //proxy class UserServiceProxy proxy = new UserServiceProxy(); //Use the agent class to realize the log function! proxy.setUserService(userService); proxy.add(); } }
In this case, the function of adding data without changing the source code is realized
Dynamic agent of JDK
The two most important classes, inovationhandler and proxy, open the jdk help documentation
Object invoke(Object proxy, method method, Object[] args); //parameter //Proxy - the proxy instance that calls the method //Method - the method corresponds to the instance that invokes the interface method on the proxy instance. The declared class of the method object will be the interface declared by the method, which can be the super interface of the proxy interface of the proxy class inheriting the method. //args - array of objects containing method calls that pass the parameter values of the proxy instance, or null if the interface method has no parameters. The parameters of the primitive type are contained in an instance of the appropriate primitive wrapper class, such as Java Lang. integer or Java lang.Boolean .
Proxy: proxy (generate proxy class)
public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getVClassLoader(),rent.getClass().getInterfaces(),this); }
---------------------------------------------Implementation in two important dynamic proxy classes
Rent.java is an abstract role
//Abstract role: rent a house public interface Rent { public void rent(); }
Host.java is the real role
//Real role: landlord, the landlord wants to rent the house public class Host implements Rent{ public void rent() { System.out.println("House rental"); } }
public class ProxyInvocationHandler implements InvocationHandler{ private Rent rent; public void setRent(Rent rent){ this.rent=rent; } //Generate an agent, focusing on the second parameter. Before obtaining the class to be represented, it was a role. Now it can represent a class of roles public Object getProxy(){ return Proxy.newProxyInstance(this.getclass.getclassLoader(),rent.getclass,getInterfaces().getiNTERFACES(),this,this); } public Object invoke(Object proxy,Method method,Obj[]args)throws Throwable{ seeHose(); Object result=method.invoke(rent,args); fare(); return result; } //House viewing public void seeHouse(){ System.out.println("Take the tenant to the doctor"); } //Intermediary fee public void fare(){ System.out.println("Intermediary fee"); } }
Client.java
public class Client{ public static void main(String[] args){ Host host=new Host(); ProcyInvocationHandler pih=new ProxyInvocationHandler(); pih.setRent(host); Rent proxy=(Rent)pih.getProxy(); proxy.rent(); } }
Through the above case, we can extract the dynamic agent class to realize the generation of tool class
public class ProxyInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } //Generate proxy class public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this); } // Proxy: proxy class // Method: the method object of the calling handler of the proxy class public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); Object result = method.invoke(target, args); return result; } public void log(String methodName){ System.out.println("Yes"+methodName+"method"); } }
Summarized dynamic proxy classes
public class Test { public static void main(String[] args) { //Real object //Real object UserServiceImpl userService = new UserServiceImpl(); //Call handler for proxy object ProxyInvocationHandler pih = new ProxyInvocationHandler(); pih.setTarget(userService); //Sets the object to proxy UserService proxy = (UserService)pih.getProxy(); //Dynamically generate proxy class! proxy.delete(); } }
It has all the static agents. It also has all the static agents that don't have!
It can make our real role more pure Stop paying attention to some public things
Public business is done by agents The division of business is realized,
When the public business expands, it becomes more centralized and convenient
A dynamic agent, generally acting for a certain kind of business
A dynamic proxy can proxy multiple classes, and the proxy is the interface!
Implementation class of AOP
The first way – through the Spring API
1. First write our business class interface and implementation class
public interface UserService { public void add(); public void delete(); public void update(); public void search(); }
public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("Add user"); } @Override public void delete() { System.out.println("delete user"); } @Override public void update() { System.out.println("Update user"); } @Override public void search() { System.out.println("Query user"); } }
Writing enhancement classes
1. Pre enhancement
public class Log implements MethodBeforeAdvice { //Method: the method of the target object to execute //objects: parameters of the called method //Object: target object @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println( o.getClass().getName() + "of" + method.getName() + "Method was executed"); } }
2. Post enhancement
public class AfterLog implements AfterReturningAdvice { //returnValue return value //Method called method //args parameter of the object of the called method //Target the called target object @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("Yes" + target.getClass().getName() +"of"+method.getName()+"method," +"Return value:"+returnValue); } }
Finally, register in the spring file and implement the aop cut in implementation. Pay attention to the import constraints
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--register bean--> <bean id="userService" class="com.kuang.service.UserServiceImpl"/> <bean id="log" class="com.kuang.log.Log"/> <bean id="afterLog" class="com.kuang.log.AfterLog"/> <!--aop Configuration of--> <aop:config> <!--breakthrough point expression:The expression matches the method to execute--> <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <!--Perform wrap; advice-ref Execution method . pointcut-ref breakthrough point--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
test
public class MyTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) context.getBean("userService"); userService.search(); } }
Custom cut in class
Write our own cut in class
public class DiyPointcut { public void before(){ System.out.println("---------Before method execution---------"); } public void after(){ System.out.println("---------After method execution---------"); } }
Go to Spring configuration
<!--The second way is to customize the implementation--> <!--register bean--> <bean id="diy" class="com.kuang.config.DiyPointcut"/> <!--aop Configuration of--> <aop:config> <!--The second way: use AOP Label Implementation of--> <aop:aspect ref="diy"> //Achieve pointcut <aop:pointcut id="diyPonitcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <aop:before pointcut-ref="diyPonitcut" method="before"/> <aop:after pointcut-ref="diyPonitcut" method="after"/> </aop:aspect> </aop:config>
test
public class MyTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) context.getBean("userService"); userService.add(); } }
Implementation using annotations
package com.kuang.config; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class AnnotationPointcut { @Before("execution(* com.kuang.service.UserServiceImpl.*(..))") public void before(){ System.out.println("---------Before method execution---------"); } @After("execution(* com.kuang.service.UserServiceImpl.*(..))") public void after(){ System.out.println("---------After method execution---------"); } @Around("execution(* com.kuang.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("Surround front"); System.out.println("autograph:"+jp.getSignature()); //Execute target method Object proceed = jp.proceed(); System.out.println("After surround"); System.out.println(proceed); } }
In the Spring configuration file, register the bean and add the supported annotation configuration
<!--The third way:Annotation implementation--> <bean id="annotationPointcut" class="com.kuang.config.AnnotationPointcut"/> <aop:aspectj-autoproxy/>
adopt aop Namespace<aop:aspectj-autoproxy />Declaration is automatically spring Which configurations are in the container@aspectJ Tangential bean Create a proxy and weave in the cut. of course, spring It is still used internally AnnotationAwareAspectJAutoProxyCreator The creation of automatic agent has been carried out, but the details of the specific implementation have been<aop:aspectj-autoproxy />It's hidden <aop:aspectj-autoproxy />There is one proxy-target-class Property, default to false,Indicates use jdk Dynamic proxy weaving enhancement when configured as<aop:aspectj-autoproxy poxy-target-class="true"/>When, it means to use CGLib Dynamic agent technology weaving enhancement. But even if proxy-target-class Set to false,If the target class does not declare an interface, then spring Will be used automatically CGLib Dynamic proxy.